microsoft/hve-core

Public

mirrored from https://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
627a87791c9fc94fbfbd596589ce6a1faaaa013d

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

320lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4
5BeforeAll {
6 . $PSScriptRoot/../../plugins/Generate-Plugins.ps1
7}
8
9Describe 'Get-AllowedCollectionMaturities' {
10 It 'Returns only stable for Stable channel' {
11 $result = Get-AllowedCollectionMaturities -Channel 'Stable'
12 $result | Should -Be @('stable')
13 }
14
15 It 'Returns stable, preview, and experimental for PreRelease channel' {
16 $result = Get-AllowedCollectionMaturities -Channel 'PreRelease'
17 $result | Should -Contain 'stable'
18 $result | Should -Contain 'preview'
19 $result | Should -Contain 'experimental'
20 }
21
22 It 'Does not include deprecated for either channel' {
23 $stable = Get-AllowedCollectionMaturities -Channel 'Stable'
24 $preRelease = Get-AllowedCollectionMaturities -Channel 'PreRelease'
25 $stable | Should -Not -Contain 'deprecated'
26 $preRelease | Should -Not -Contain 'deprecated'
27 }
28}
29
30Describe 'Select-CollectionItemsByChannel' {
31 It 'Includes stable items on Stable channel' {
32 $collection = @{
33 id = 'test'
34 items = @(
35 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' }
36 )
37 }
38 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
39 $result.items.Count | Should -Be 1
40 }
41
42 It 'Excludes preview items on Stable channel' {
43 $collection = @{
44 id = 'test'
45 items = @(
46 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
47 @{ kind = 'agent'; path = '.github/agents/b.agent.md'; maturity = 'preview' }
48 )
49 }
50 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
51 $result.items.Count | Should -Be 1
52 }
53
54 It 'Includes preview and experimental items on PreRelease channel' {
55 $collection = @{
56 id = 'test'
57 items = @(
58 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
59 @{ kind = 'prompt'; path = '.github/prompts/b.prompt.md'; maturity = 'preview' },
60 @{ kind = 'instruction'; path = '.github/instructions/c.instructions.md'; maturity = 'experimental' }
61 )
62 }
63 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'PreRelease'
64 $result.items.Count | Should -Be 3
65 }
66
67 It 'Excludes deprecated items on PreRelease channel' {
68 $collection = @{
69 id = 'test'
70 items = @(
71 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' },
72 @{ kind = 'agent'; path = '.github/agents/old.agent.md'; maturity = 'deprecated' }
73 )
74 }
75 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'PreRelease'
76 $result.items.Count | Should -Be 1
77 }
78
79 It 'Defaults to stable when maturity is null' {
80 $collection = @{
81 id = 'test'
82 items = @(
83 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = $null }
84 )
85 }
86 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
87 $result.items.Count | Should -Be 1
88 }
89
90 It 'Preserves non-items keys from collection' {
91 $collection = @{
92 id = 'test'
93 name = 'Test Collection'
94 description = 'desc'
95 items = @(
96 @{ kind = 'agent'; path = '.github/agents/a.agent.md'; maturity = 'stable' }
97 )
98 }
99 $result = Select-CollectionItemsByChannel -Collection $collection -Channel 'Stable'
100 $result.id | Should -Be 'test'
101 $result.name | Should -Be 'Test Collection'
102 $result.description | Should -Be 'desc'
103 }
104}
105
106Describe 'Invoke-PluginGeneration' {
107 BeforeAll {
108 $script:tempDir = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
109 New-Item -ItemType Directory -Path $script:tempDir -Force | Out-Null
110
111 # Create package.json
112 @{
113 name = 'hve-core'
114 version = '1.0.0'
115 description = 'test'
116 author = 'test-author'
117 } | ConvertTo-Json | Set-Content -Path (Join-Path $script:tempDir 'package.json')
118
119 # Create collections directory with manifests
120 $collectionsDir = Join-Path $script:tempDir 'collections'
121 New-Item -ItemType Directory -Path $collectionsDir -Force | Out-Null
122
123 # Create .github structure with artifacts
124 $ghDir = Join-Path $script:tempDir '.github'
125 $agentsDir = Join-Path $ghDir 'agents'
126 $promptsDir = Join-Path $ghDir 'prompts'
127 $instrDir = Join-Path $ghDir 'instructions'
128 $skillsDir = Join-Path $ghDir 'skills/test-skill'
129 New-Item -ItemType Directory -Path $agentsDir -Force | Out-Null
130 New-Item -ItemType Directory -Path $promptsDir -Force | Out-Null
131 New-Item -ItemType Directory -Path $instrDir -Force | Out-Null
132 New-Item -ItemType Directory -Path $skillsDir -Force | Out-Null
133
134 @'
135---
136description: "Test agent"
137---
138'@ | Set-Content -Path (Join-Path $agentsDir 'test.agent.md')
139
140 @'
141---
142description: "Test prompt"
143---
144'@ | Set-Content -Path (Join-Path $promptsDir 'test.prompt.md')
145
146 @'
147---
148description: "Test instruction"
149applyTo: "**/*.ps1"
150---
151'@ | Set-Content -Path (Join-Path $instrDir 'test.instructions.md')
152
153 @'
154---
155name: test-skill
156description: "Test skill"
157---
158'@ | Set-Content -Path (Join-Path $skillsDir 'SKILL.md')
159
160 # Create docs/templates and scripts directories for shared symlinking
161 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'docs/templates') -Force | Out-Null
162 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'scripts/lib') -Force | Out-Null
163
164 # Create plugins directory
165 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'plugins') -Force | Out-Null
166
167 # Create .github/plugin directory for marketplace manifest
168 New-Item -ItemType Directory -Path (Join-Path $script:tempDir '.github/plugin') -Force | Out-Null
169
170 # hve-core-all collection
171 @"
172id: hve-core-all
173name: hve-core
174description: All artifacts
175tags:
176 - copilot
177items:
178 - path: .github/agents/test.agent.md
179 kind: agent
180 - path: .github/prompts/test.prompt.md
181 kind: prompt
182 - path: .github/instructions/test.instructions.md
183 kind: instruction
184 - path: .github/skills/test-skill
185 kind: skill
186display:
187 color: blue
188"@ | Set-Content -Path (Join-Path $collectionsDir 'hve-core-all.collection.yml')
189 }
190
191 AfterAll {
192 Remove-Item -Path $script:tempDir -Recurse -Force -ErrorAction SilentlyContinue
193 }
194
195 It 'Generates plugins successfully' {
196 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -Refresh -Channel 'PreRelease'
197 $result.Success | Should -BeTrue
198 $result.PluginCount | Should -BeGreaterOrEqual 1
199 }
200
201 It 'Creates plugin directory' {
202 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
203 Test-Path $pluginDir | Should -BeTrue
204 }
205
206 It 'Generates plugin.json manifest' {
207 $manifestPath = Join-Path $script:tempDir 'plugins/hve-core-all/.github/plugin/plugin.json'
208 Test-Path $manifestPath | Should -BeTrue
209 $manifest = Get-Content -Path $manifestPath -Raw | ConvertFrom-Json
210 $manifest.name | Should -Be 'hve-core-all'
211 }
212
213 It 'Generates README.md' {
214 $readmePath = Join-Path $script:tempDir 'plugins/hve-core-all/README.md'
215 Test-Path $readmePath | Should -BeTrue
216 }
217
218 It 'Filters to specific collection IDs when provided' {
219 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
220 $result.PluginCount | Should -Be 1
221 }
222
223 It 'Warns for non-existent collection IDs' {
224 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('nonexistent') -Refresh -Channel 'PreRelease' 3>&1
225 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
226 $warnings.Count | Should -BeGreaterOrEqual 1
227 }
228
229 It 'Supports DryRun mode' {
230 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -DryRun -Channel 'PreRelease'
231 $result.Success | Should -BeTrue
232 }
233
234 It 'Returns zero plugins when no collections found' {
235 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
236 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'collections') -Force | Out-Null
237 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
238 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
239 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
240
241 # Create minimal .github structure for auto-update
242 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
243 @"
244id: hve-core-all
245name: hve-core
246description: test
247tags: []
248items: []
249display: {}
250"@ | Set-Content -Path (Join-Path $emptyRoot 'collections/hve-core-all.collection.yml')
251
252 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -CollectionIds @('missing-id') -Channel 'PreRelease' 3>&1
253 $hashtableResult = $result | Where-Object { $_ -is [hashtable] }
254 if ($hashtableResult) {
255 $hashtableResult.PluginCount | Should -Be 0
256 }
257 }
258
259 It 'Applies channel filtering to items' {
260 # Add a collection with mixed maturities
261 $mixedPath = Join-Path (Join-Path $script:tempDir 'collections') 'mixed.collection.yml'
262 @"
263id: mixed
264name: Mixed Collection
265description: Mixed maturity test
266items:
267 - path: .github/agents/test.agent.md
268 kind: agent
269 maturity: stable
270 - path: .github/prompts/test.prompt.md
271 kind: prompt
272 maturity: experimental
273"@ | Set-Content -Path $mixedPath
274
275 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('mixed') -Refresh -Channel 'Stable'
276 $result.Success | Should -BeTrue
277 }
278
279 It 'Removes existing plugin directory on Refresh' {
280 # Create a stale file in plugin dir
281 $staleDir = Join-Path $script:tempDir 'plugins/hve-core-all/stale'
282 New-Item -ItemType Directory -Path $staleDir -Force | Out-Null
283 'stale' | Set-Content -Path (Join-Path $staleDir 'file.txt')
284
285 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
286 $result.Success | Should -BeTrue
287 Test-Path $staleDir | Should -BeFalse
288 }
289
290 It 'Logs DryRun message when refreshing existing plugin' {
291 # Ensure plugin directory exists
292 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
293 New-Item -ItemType Directory -Path $pluginDir -Force | Out-Null
294
295 $output = Invoke-PluginGeneration -RepoRoot $script:tempDir `
296 -CollectionIds @('hve-core-all') `
297 -Refresh -DryRun -Channel 'PreRelease' 6>&1
298
299 $dryRunMessages = @($output | Where-Object { "$_" -match 'DRY RUN.*Would remove' })
300 $dryRunMessages.Count | Should -BeGreaterOrEqual 1
301 }
302
303 It 'Warns when collections directory has no matching YAML files' {
304 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
305 $emptyCollDir = Join-Path $emptyRoot 'collections'
306 New-Item -ItemType Directory -Path $emptyCollDir -Force | Out-Null
307 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
308 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
309 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
310 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
311
312 # Mock Update-HveCoreAllCollection to avoid file-not-found errors
313 Mock Update-HveCoreAllCollection { return @{ ItemCount = 0; AddedCount = 0; RemovedCount = 0 } }
314
315 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -Channel 'PreRelease' 3>&1
316 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
317 $warnings.Count | Should -BeGreaterOrEqual 1
318 $warnings[0].Message | Should -Match 'No collection manifests found'
319 }
320}
321