microsoft/hve-core

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
hve-core-v2.3.6

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

321lines · 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/dev-tools') -Force | Out-Null
163 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'scripts/lib') -Force | Out-Null
164
165 # Create plugins directory
166 New-Item -ItemType Directory -Path (Join-Path $script:tempDir 'plugins') -Force | Out-Null
167
168 # Create .github/plugin directory for marketplace manifest
169 New-Item -ItemType Directory -Path (Join-Path $script:tempDir '.github/plugin') -Force | Out-Null
170
171 # hve-core-all collection
172 @"
173id: hve-core-all
174name: hve-core
175description: All artifacts
176tags:
177 - copilot
178items:
179 - path: .github/agents/test.agent.md
180 kind: agent
181 - path: .github/prompts/test.prompt.md
182 kind: prompt
183 - path: .github/instructions/test.instructions.md
184 kind: instruction
185 - path: .github/skills/test-skill
186 kind: skill
187display:
188 color: blue
189"@ | Set-Content -Path (Join-Path $collectionsDir 'hve-core-all.collection.yml')
190 }
191
192 AfterAll {
193 Remove-Item -Path $script:tempDir -Recurse -Force -ErrorAction SilentlyContinue
194 }
195
196 It 'Generates plugins successfully' {
197 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -Refresh -Channel 'PreRelease'
198 $result.Success | Should -BeTrue
199 $result.PluginCount | Should -BeGreaterOrEqual 1
200 }
201
202 It 'Creates plugin directory' {
203 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
204 Test-Path $pluginDir | Should -BeTrue
205 }
206
207 It 'Generates plugin.json manifest' {
208 $manifestPath = Join-Path $script:tempDir 'plugins/hve-core-all/.github/plugin/plugin.json'
209 Test-Path $manifestPath | Should -BeTrue
210 $manifest = Get-Content -Path $manifestPath -Raw | ConvertFrom-Json
211 $manifest.name | Should -Be 'hve-core-all'
212 }
213
214 It 'Generates README.md' {
215 $readmePath = Join-Path $script:tempDir 'plugins/hve-core-all/README.md'
216 Test-Path $readmePath | Should -BeTrue
217 }
218
219 It 'Filters to specific collection IDs when provided' {
220 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
221 $result.PluginCount | Should -Be 1
222 }
223
224 It 'Warns for non-existent collection IDs' {
225 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('nonexistent') -Refresh -Channel 'PreRelease' 3>&1
226 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
227 $warnings.Count | Should -BeGreaterOrEqual 1
228 }
229
230 It 'Supports DryRun mode' {
231 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -DryRun -Channel 'PreRelease'
232 $result.Success | Should -BeTrue
233 }
234
235 It 'Returns zero plugins when no collections found' {
236 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
237 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'collections') -Force | Out-Null
238 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
239 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
240 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
241
242 # Create minimal .github structure for auto-update
243 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
244 @"
245id: hve-core-all
246name: hve-core
247description: test
248tags: []
249items: []
250display: {}
251"@ | Set-Content -Path (Join-Path $emptyRoot 'collections/hve-core-all.collection.yml')
252
253 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -CollectionIds @('missing-id') -Channel 'PreRelease' 3>&1
254 $hashtableResult = $result | Where-Object { $_ -is [hashtable] }
255 if ($hashtableResult) {
256 $hashtableResult.PluginCount | Should -Be 0
257 }
258 }
259
260 It 'Applies channel filtering to items' {
261 # Add a collection with mixed maturities
262 $mixedPath = Join-Path (Join-Path $script:tempDir 'collections') 'mixed.collection.yml'
263 @"
264id: mixed
265name: Mixed Collection
266description: Mixed maturity test
267items:
268 - path: .github/agents/test.agent.md
269 kind: agent
270 maturity: stable
271 - path: .github/prompts/test.prompt.md
272 kind: prompt
273 maturity: experimental
274"@ | Set-Content -Path $mixedPath
275
276 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('mixed') -Refresh -Channel 'Stable'
277 $result.Success | Should -BeTrue
278 }
279
280 It 'Removes existing plugin directory on Refresh' {
281 # Create a stale file in plugin dir
282 $staleDir = Join-Path $script:tempDir 'plugins/hve-core-all/stale'
283 New-Item -ItemType Directory -Path $staleDir -Force | Out-Null
284 'stale' | Set-Content -Path (Join-Path $staleDir 'file.txt')
285
286 $result = Invoke-PluginGeneration -RepoRoot $script:tempDir -CollectionIds @('hve-core-all') -Refresh -Channel 'PreRelease'
287 $result.Success | Should -BeTrue
288 Test-Path $staleDir | Should -BeFalse
289 }
290
291 It 'Logs DryRun message when refreshing existing plugin' {
292 # Ensure plugin directory exists
293 $pluginDir = Join-Path $script:tempDir 'plugins/hve-core-all'
294 New-Item -ItemType Directory -Path $pluginDir -Force | Out-Null
295
296 $output = Invoke-PluginGeneration -RepoRoot $script:tempDir `
297 -CollectionIds @('hve-core-all') `
298 -Refresh -DryRun -Channel 'PreRelease' 6>&1
299
300 $dryRunMessages = @($output | Where-Object { "$_" -match 'DRY RUN.*Would remove' })
301 $dryRunMessages.Count | Should -BeGreaterOrEqual 1
302 }
303
304 It 'Warns when collections directory has no matching YAML files' {
305 $emptyRoot = Join-Path $TestDrive ([System.Guid]::NewGuid().ToString())
306 $emptyCollDir = Join-Path $emptyRoot 'collections'
307 New-Item -ItemType Directory -Path $emptyCollDir -Force | Out-Null
308 New-Item -ItemType Directory -Path (Join-Path $emptyRoot 'plugins') -Force | Out-Null
309 New-Item -ItemType Directory -Path (Join-Path $emptyRoot '.github/agents') -Force | Out-Null
310 @{ name = 'test'; version = '1.0.0'; description = 'test'; author = 'test' } |
311 ConvertTo-Json | Set-Content -Path (Join-Path $emptyRoot 'package.json')
312
313 # Mock Update-HveCoreAllCollection to avoid file-not-found errors
314 Mock Update-HveCoreAllCollection { return @{ ItemCount = 0; AddedCount = 0; RemovedCount = 0 } }
315
316 $result = Invoke-PluginGeneration -RepoRoot $emptyRoot -Channel 'PreRelease' 3>&1
317 $warnings = @($result | Where-Object { $_ -is [System.Management.Automation.WarningRecord] })
318 $warnings.Count | Should -BeGreaterOrEqual 1
319 $warnings[0].Message | Should -Match 'No collection manifests found'
320 }
321}
322