microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix/dependabot-uuid-postcss-overrides

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/tests/plugins/Generate-Plugins.Tests.ps1

563lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4
5BeforeAll {
6 . $PSScriptRoot/../../plugins/Generate-Plugins.ps1
7 # Re-import CollectionHelpers after dot-sourcing because PluginHelpers internally
8 # imports CollectionHelpers with -Force, removing it from the caller's scope.
9 Import-Module (Join-Path $PSScriptRoot '../../collections/Modules/CollectionHelpers.psm1') -Force
10}
11
12Describe 'Get-AllowedCollectionMaturities' {
13 It 'Returns only stable for Stable channel' {
14 $result = Get-AllowedCollectionMaturities -Channel 'Stable'
15 $result | Should -Be @('stable')
16 }
17
18 It 'Returns stable, preview, and experimental for PreRelease channel' {
19 $result = Get-AllowedCollectionMaturities -Channel 'PreRelease'
20 $result | Should -Contain 'stable'
21 $result | Should -Contain 'preview'
22 $result | Should -Contain 'experimental'
23 }
24
25 It 'Does not include deprecated for either channel' {
26 $stable = Get-AllowedCollectionMaturities -Channel 'Stable'
27 $preRelease = Get-AllowedCollectionMaturities -Channel 'PreRelease'
28 $stable | Should -Not -Contain 'deprecated'
29 $preRelease | Should -Not -Contain 'deprecated'
30 }
31
32 It 'Does not include removed for either channel' {
33 $stable = Get-AllowedCollectionMaturities -Channel 'Stable'
34 $preRelease = Get-AllowedCollectionMaturities -Channel 'PreRelease'
35 $stable | Should -Not -Contain 'removed'
36 $preRelease | Should -Not -Contain 'removed'
37 }
38}
39
40Describe 'Select-CollectionItemsByChannel' {
41 It 'Includes stable items on Stable channel' {
42 $collection = @{
43 id = 'test'
44 items = @(
45 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' }
46 )
47 }
48 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
49 $result.items.Count | Should -Be 1
50 }
51
52 It 'Excludes preview items on Stable channel' {
53 $collection = @{
54 id = 'test'
55 items = @(
56 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
57 @{ kind = 'agent'; path = '.github/agents/b.agent.md'; maturity = 'preview' }
58 )
59 }
60 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
61 $result.items.Count | Should -Be 1
62 }
63
64 It 'Includes preview and experimental items on PreRelease channel' {
65 $collection = @{
66 id = 'test'
67 items = @(
68 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
69 @{ kind = 'prompt'; path = '.github/prompts/b.prompt.md'; maturity = 'preview' },
70 @{ kind = 'instruction'; path = '.github/instructions/c.instructions.md'; maturity = 'experimental' }
71 )
72 }
73 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'PreRelease'
74 $result.items.Count | Should -Be 3
75 }
76
77 It 'Excludes deprecated items on PreRelease channel' {
78 $collection = @{
79 id = 'test'
80 items = @(
81 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
82 @{ kind = 'agent'; path = '.github/agents/old.agent.md'; maturity = 'deprecated' }
83 )
84 }
85 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'PreRelease'
86 $result.items.Count | Should -Be 1
87 }
88
89 It 'Excludes removed items on Stable channel' {
90 $collection = @{
91 id = 'test'
92 items = @(
93 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
94 @{ kind = 'agent'; path = '.github/agents/gone.agent.md'; maturity = 'removed' }
95 )
96 }
97 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
98 $result.items.Count | Should -Be 1
99 }
100
101 It 'Excludes removed items on PreRelease channel' {
102 $collection = @{
103 id = 'test'
104 items = @(
105 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
106 @{ kind = 'agent'; path = '.github/agents/gone.agent.md'; maturity = 'removed' }
107 )
108 }
109 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'PreRelease'
110 $result.items.Count | Should -Be 1
111 }
112
113 It 'Defaults to stable when maturity is null' {
114 $collection = @{
115 id = 'test'
116 items = @(
117 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = $null }
118 )
119 }
120 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
121 $result.items.Count | Should -Be 1
122 }
123
124 It 'Preserves non-items keys from collection' {
125 $collection = @{
126 id = 'test'
127 name = 'Test Collection'
128 description = 'desc'
129 items = @(
130 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' }
131 )
132 }
133 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
134 $result.id | Should -Be 'test'
135 $result.name | Should -Be 'Test Collection'
136 $result.description | Should -Be 'desc'
137 }
138}
139
140Describe 'Invoke-PluginGeneration - collection-level maturity' {
141 BeforeAll {
142 $script:maturityDir = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
143 New-Item -ItemType Directory -Path $script:maturityDir -Force | Out-Null
144
145 # Create package.json
146 @{
147 name = 'hve-core'
148 version = '1.0.0'
149 description = 'test'
150 author = 'test-author'
151 } | ConvertTo-Json | Set-Content -Path (Join-Path $script:maturityDir 'package.json')
152
153 # Create collections directory
154 $collectionsDir = Join-Path $script:maturityDir 'collections'
155 New-Item -ItemType Directory -Path $collectionsDir -Force | Out-Null
156
157 # Create .github structure with a test artifact
158 $ghDir = Join-Path $script:maturityDir '.github'
159 $agentsDir = Join-Path $ghDir 'agents/col'
160 New-Item -ItemType Directory -Path $agentsDir -Force | Out-Null
161 @'
162---
163description: "Test agent"
164---
165'@ | Set-Content -Path (Join-Path $agentsDir 'test.agent.md')
166
167 # Create shared directories for symlinks
168 New-Item -ItemType Directory -Path (Join-Path $script:maturityDir 'docs/templates') -Force | Out-Null
169 New-Item -ItemType Directory -Path (Join-Path $script:maturityDir 'scripts/lib') -Force | Out-Null
170
171 # Create plugins directory
172 New-Item -ItemType Directory -Path (Join-Path $script:maturityDir 'plugins') -Force | Out-Null
173
174 # Create .github/plugin directory
175 New-Item -ItemType Directory -Path (Join-Path $script:maturityDir '.github/plugin') -Force | Out-Null
176
177 # hve-core-all collection (required by Update-HveCoreAllCollection)
178 @"
179id: hve-core-all
180name: hve-core
181description: All artifacts
182tags: []
183items:
184 - path: .github/agents/col/test.agent.md
185 kind: agent
186display: {}
187"@ | Set-Content -Path (Join-Path $collectionsDir 'hve-core-all.collection.yml')
188
189 # Deprecated collection
190 @"
191id: deprecated-col
192name: Deprecated Collection
193description: A deprecated collection
194maturity: deprecated
195items:
196 - path: .github/agents/col/test.agent.md
197 kind: agent
198"@ | Set-Content -Path (Join-Path $collectionsDir 'deprecated-col.collection.yml')
199
200 # Experimental collection
201 @"
202id: experimental-col
203name: Experimental Collection
204description: An experimental collection
205maturity: experimental
206items:
207 - path: .github/agents/col/test.agent.md
208 kind: agent
209"@ | Set-Content -Path (Join-Path $collectionsDir 'experimental-col.collection.yml')
210 }
211
212 AfterAll {
213 Remove-Item -Path $script:maturityDir -Recurse -Force -ErrorAction SilentlyContinue
214 }
215
216 It 'Skips deprecated collection during generation' {
217 Invoke-PluginGeneration -RepoRoot $script:maturityDir -CollectionIds @('deprecated-col') -Refresh -Channel 'PreRelease' | Out-Null
218 $pluginDir = Join-Path $script:maturityDir 'plugins/deprecated-col'
219 Test-Path $pluginDir | Should -BeFalse
220 }
221
222 It 'Generates experimental collection on PreRelease channel' {
223 Invoke-PluginGeneration -RepoRoot $script:maturityDir -CollectionIds @('experimental-col') -Refresh -Channel 'PreRelease' | Out-Null
224 $pluginDir = Join-Path $script:maturityDir 'plugins/experimental-col'
225 Test-Path $pluginDir | Should -BeTrue
226 }
227}
228
229Describe 'Invoke-PluginGeneration' {
230 BeforeAll {
231 $script:tempDir = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
232 New-Item -ItemType Directory -Path $script:tempDir -Force | Out-Null
233
234 # Create package.json
235 @{
236 name = 'hve-core'
237 version = '1.0.0'
238 description = 'test'
239 author = 'test-author'
240 } | ConvertTo-Json | Set-Content -Path (Join-Path $script:tempDir 'package.json')
241
242 # Create collections directory with manifests
243 $collectionsDir = Join-Path $script:tempDir 'collections'
244 New-Item -ItemType Directory -Path $collectionsDir -Force | Out-Null
245
246 # Create .github structure with artifacts
247 $ghDir = Join-Path $script:tempDir '.github'
248 $agentsDir = Join-Path $ghDir 'agents'
249 $promptsDir = Join-Path $ghDir 'prompts'
250 $instrDir = Join-Path $ghDir 'instructions'
251 $skillsDir = Join-Path $ghDir 'skills/test-skill'
252 New-Item -ItemType Directory -Path $agentsDir -Force | Out-Null
253 New-Item -ItemType Directory -Path $promptsDir -Force | Out-Null
254 New-Item -ItemType Directory -Path $instrDir -Force | Out-Null
255 New-Item -ItemType Directory -Path $skillsDir -Force | Out-Null
256
257 @'
258---
259description: "Test agent"
260---
261'@ | Set-Content -Path (Join-Path $agentsDir 'test.agent.md')
262
263 @'
264---
265description: "Test prompt"
266---
267'@ | Set-Content -Path (Join-Path $promptsDir 'test.prompt.md')
268
269 @'
270---
271description: "Test instruction"
272applyTo: "**/*.ps1"
273---
274'@ | Set-Content -Path (Join-Path $instrDir 'test.instructions.md')
275
276 @'
277---
278name: test-skill
279description: "Test skill"
280---
281'@ | Set-Content -Path (Join-Path $skillsDir 'SKILL.md')
282
283 # Create docs/templates and scripts directories for shared symlinking
284 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'docs/templates') -Force | Out-Null
285 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'scripts/lib') -Force | Out-Null
286
287 # Create plugins directory
288 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'plugins') -Force | Out-Null
289
290 # Create .github/plugin directory for marketplace manifest
291 New-Item -ItemType Directory -Path (Join-Path $script:tempDir '.github/plugin') -Force | Out-Null
292
293 # hve-core-all collection
294 @"
295id: hve-core-all
296name: hve-core
297description: All artifacts
298tags:
299 - copilot
300items:
301 - path: .github/agents/test.agent.md
302 kind: agent
303 - path: .github/prompts/test.prompt.md
304 kind: prompt
305 - path: .github/instructions/test.instructions.md
306 kind: instruction
307 - path: .github/skills/test-skill
308 kind: skill
309display:
310 color: blue
311"@ | Set-Content -Path (Join-Path $collectionsDir 'hve-core-all.collection.yml')
312 }
313
314 AfterAll {
315 Remove-Item -Path $script:tempDir -Recurse -Force -ErrorAction SilentlyContinue
316 }
317
318 It 'Generates plugins successfully' {
319 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -Refresh -Channel 'PreRelease'
320 $result.Success | Should -BeTrue
321 $result.PluginCount | Should -BeGreaterOrEqual 1
322 }
323
324 It 'Creates plugin directory' {
325 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
326 Test-Path $pluginDir | Should -BeTrue
327 }
328
329 It 'Generates plugin.json manifest' {
330 $manifestPath = Join-Path $script:tempDir 'plugins/hve-core-all/.github/plugin/plugin.json'
331 Test-Path $manifestPath | Should -BeTrue
332 $manifest = Get-Content -Path $manifestPath -Raw | ConvertFrom-Json
333 $manifest.name | Should -Be 'hve-core-all'
334 }
335
336 It 'Generates README.md' {
337 $readmePath = Join-Path $script:tempDir 'plugins/hve-core-all/README.md'
338 Test-Path $readmePath | Should -BeTrue
339 }
340
341 It 'Filters to specific collection IDs when provided' {
342 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
343 $result.PluginCount | Should -Be 1
344 }
345
346 It 'Warns for non-existent collection IDs' {
347 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('nonexistent') -Refresh -Channel 'PreRelease' 3>&1
348 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
349 $warnings.Count | Should -BeGreaterOrEqual 1
350 }
351
352 It 'Supports DryRun mode' {
353 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -DryRun -Channel 'PreRelease'
354 $result.Success | Should -BeTrue
355 }
356
357 It 'Returns zero plugins when no collections found' {
358 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
359 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'collections') -Force | Out-Null
360 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
361 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
362 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
363
364 # Create minimal .github structure for auto-update
365 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
366 @"
367id: hve-core-all
368name: hve-core
369description: test
370tags: []
371items: []
372display: {}
373"@ | Set-Content -Path (Join-Path $emptyRoot 'collections/hve-core-all.collection.yml')
374
375 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -CollectionIds @('missing-id') -Channel 'PreRelease' 3>&1
376 $hashtableResult = $result | Where-Object { $_ -is [hashtable] }
377 if ($hashtableResult) {
378 $hashtableResult.PluginCount | Should -Be 0
379 }
380 }
381
382 It 'Applies channel filtering to items' {
383 # Add a collection with mixed maturities
384 $mixedPath = Join-Path (Join-Path $script:tempDir 'collections') 'mixed.collection.yml'
385 @"
386id: mixed
387name: Mixed Collection
388description: Mixed maturity test
389items:
390 - path: .github/agents/test.agent.md
391 kind: agent
392 maturity: stable
393 - path: .github/prompts/test.prompt.md
394 kind: prompt
395 maturity: experimental
396"@ | Set-Content -Path $mixedPath
397
398 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('mixed') -Refresh -Channel 'Stable'
399 $result.Success | Should -BeTrue
400 }
401
402 It 'Removes orphan files on Refresh' {
403 # Create a stale file in plugin dir
404 $staleDir = Join-Path $script:tempDir 'plugins/hve-core-all/stale'
405 New-Item -ItemType Directory -Path $staleDir -Force | Out-Null
406 'stale' | Set-Content -Path (Join-Path $staleDir 'file.txt')
407
408 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
409 $result.Success | Should -BeTrue
410 # Orphan file and its now-empty parent directory are removed
411 Test-Path (Join-Path $staleDir 'file.txt') | Should -BeFalse
412 Test-Path $staleDir | Should -BeFalse
413 # Plugin directory itself still exists with generated files
414 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
415 Test-Path $pluginDir | Should -BeTrue
416 Test-Path (Join-Path $pluginDir 'README.md') | Should -BeTrue
417 }
418
419 It 'Logs DryRun message when refreshing existing plugin' {
420 # Create orphan file so DryRun has something to report
421 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
422 $orphanDir = Join-Path $pluginDir 'stale-dry'
423 New-Item -ItemType Directory -Path $orphanDir -Force | Out-Null
424 'stale' | Set-Content -Path (Join-Path $orphanDir 'file.txt')
425
426 $output = Invoke-PluginGeneration -RepoRoot $script:tempDir `
427 -CollectionIds @('hve-core-all') `
428 -Refresh -DryRun -Channel 'PreRelease' 6>&1
429
430 $dryRunMessages = @($output | Where-Object { "$_" -match 'DRY RUN.*Would remove orphan' })
431 $dryRunMessages.Count | Should -BeGreaterOrEqual 1
432 }
433
434 It 'Warns when collections directory has no matching YAML files' {
435 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
436 $emptyCollDir = Join-Path $emptyRoot 'collections'
437 New-Item -ItemType Directory -Path $emptyCollDir -Force | Out-Null
438 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
439 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
440 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
441 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
442
443 # Mock Update-HveCoreAllCollection to avoid file-not-found errors
444 Mock Update-HveCoreAllCollection { return @{ ItemCount = 0; AddedCount = 0; RemovedCount = 0 } }
445
446 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -Channel 'PreRelease' 3>&1
447 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
448 $warnings.Count | Should -BeGreaterOrEqual 1
449 $warnings[0].Message | Should -Match 'No collection manifests found'
450 }
451
452 It 'Outputs verbose symlink capability detection' {
453 $output = Invoke-PluginGeneration -RepoRoot $script:tempDir `
454 -CollectionIds @('hve-core-all') `
455 -Channel 'PreRelease' -Verbose 4>&1
456
457 $capMsg = @($output | Where-Object { "$_" -match 'Symlink capability' })
458 $capMsg.Count | Should -BeGreaterOrEqual 1
459 }
460
461 Context 'Orphan Cleanup' {
462 It 'Removes orphan files after overwrite-in-place' {
463 $staleDir = Join-Path $script:tempDir 'plugins/hve-core-all/orphan-test'
464 New-Item -ItemType Directory -Path $staleDir -Force | Out-Null
465 'stale' | Set-Content -Path (Join-Path $staleDir 'leftover.txt')
466
467 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
468 $result.Success | Should -BeTrue
469 Test-Path (Join-Path $staleDir 'leftover.txt') | Should -BeFalse
470 Test-Path (Join-Path $script:tempDir 'plugins/hve-core-all/README.md') | Should -BeTrue
471 }
472
473 It 'Preserves generated files during cleanup' {
474 # Run a fresh Refresh to get clean state
475 Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease' | Out-Null
476
477 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
478 Test-Path (Join-Path $pluginDir 'README.md') | Should -BeTrue
479 Test-Path (Join-Path $pluginDir '.github/plugin/plugin.json') | Should -BeTrue
480 Test-Path (Join-Path $pluginDir 'docs/templates') | Should -BeTrue
481 Test-Path (Join-Path $pluginDir 'scripts/lib') | Should -BeTrue
482 }
483
484 It 'Removes empty directories after orphan cleanup' {
485 $nestedOrphan = Join-Path $script:tempDir 'plugins/hve-core-all/stale-dir/nested'
486 New-Item -ItemType Directory -Path $nestedOrphan -Force | Out-Null
487 'leftover' | Set-Content -Path (Join-Path $nestedOrphan 'leftover.txt')
488
489 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
490 $result.Success | Should -BeTrue
491 Test-Path (Join-Path $script:tempDir 'plugins/hve-core-all/stale-dir') | Should -BeFalse
492 }
493
494 It 'DryRun logs orphan files without removing them' {
495 $orphanDir = Join-Path $script:tempDir 'plugins/hve-core-all/dry-orphan'
496 New-Item -ItemType Directory -Path $orphanDir -Force | Out-Null
497 'keep-me' | Set-Content -Path (Join-Path $orphanDir 'persist.txt')
498
499 $output = Invoke-PluginGeneration -RepoRoot $script:tempDir `
500 -CollectionIds @('hve-core-all') `
501 -Refresh -DryRun -Channel 'PreRelease' 6>&1
502
503 $dryRunMessages = @($output | Where-Object { "$_" -match 'DRY RUN.*Would remove orphan' })
504 $dryRunMessages.Count | Should -BeGreaterOrEqual 1
505 # File still exists after DryRun
506 Test-Path (Join-Path $orphanDir 'persist.txt') | Should -BeTrue
507 }
508 }
509}
510
511Describe 'Start-PluginGeneration' {
512 It 'Returns 0 on successful generation' {
513 Mock Invoke-PluginGeneration { return @{ Success = $true; PluginCount = 2 } }
514 Mock Get-Module { return @{ Name = 'PowerShell-Yaml' } } -ParameterFilter { $ListAvailable -and $Name -eq 'PowerShell-Yaml' }
515 Mock Import-Module {}
516
517 $scriptPath = "$PSScriptRoot/../../plugins/Generate-Plugins.ps1"
518 $exitCode = Start-PluginGeneration -ScriptPath $scriptPath -Channel 'PreRelease'
519 $exitCode | Should -Be 0
520 }
521
522 It 'Returns 1 when Invoke-PluginGeneration reports failure' {
523 Mock Invoke-PluginGeneration { return @{ Success = $false; PluginCount = 0; ErrorMessage = 'Generation failed' } }
524 Mock Get-Module { return @{ Name = 'PowerShell-Yaml' } } -ParameterFilter { $ListAvailable -and $Name -eq 'PowerShell-Yaml' }
525 Mock Import-Module {}
526
527 $scriptPath = "$PSScriptRoot/../../plugins/Generate-Plugins.ps1"
528 $output = Start-PluginGeneration -ScriptPath $scriptPath -Channel 'PreRelease' -ErrorAction SilentlyContinue
529 $exitCode = @($output) | Where-Object { $_ -is [int] } | Select-Object -Last 1
530 $exitCode | Should -Be 1
531 }
532
533 It 'Returns 1 when PowerShell-Yaml module is missing' {
534 Mock Get-Module { return $null } -ParameterFilter { $ListAvailable -and $Name -eq 'PowerShell-Yaml' }
535
536 $scriptPath = "$PSScriptRoot/../../plugins/Generate-Plugins.ps1"
537 $output = Start-PluginGeneration -ScriptPath $scriptPath -Channel 'PreRelease' -ErrorAction SilentlyContinue
538 $exitCode = @($output) | Where-Object { $_ -is [int] } | Select-Object -Last 1
539 $exitCode | Should -Be 1
540 }
541
542 It 'Defaults to refresh when no CollectionIds, Refresh, or DryRun provided' {
543 Mock Get-Module { return @{ Name = 'PowerShell-Yaml' } } -ParameterFilter { $ListAvailable -and $Name -eq 'PowerShell-Yaml' }
544 Mock Import-Module {}
545 Mock Invoke-PluginGeneration { return @{ Success = $true; PluginCount = 1 } }
546
547 $scriptPath = "$PSScriptRoot/../../plugins/Generate-Plugins.ps1"
548 Start-PluginGeneration -ScriptPath $scriptPath -Channel 'PreRelease' | Out-Null
549
550 Should -Invoke Invoke-PluginGeneration -Times 1 -ParameterFilter { $Refresh -eq $true }
551 }
552
553 It 'Does not force refresh when CollectionIds are provided' {
554 Mock Get-Module { return @{ Name = 'PowerShell-Yaml' } } -ParameterFilter { $ListAvailable -and $Name -eq 'PowerShell-Yaml' }
555 Mock Import-Module {}
556 Mock Invoke-PluginGeneration { return @{ Success = $true; PluginCount = 1 } }
557
558 $scriptPath = "$PSScriptRoot/../../plugins/Generate-Plugins.ps1"
559 Start-PluginGeneration -ScriptPath $scriptPath -CollectionIds @('test') -Channel 'PreRelease' | Out-Null
560
561 Should -Invoke Invoke-PluginGeneration -Times 1 -ParameterFilter { $Refresh -eq $false }
562 }
563}
564