microsoft/hve-core

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
feat/a11y-pr1-scripts-validators

Branches

Tags

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

Clone

HTTPS

Download ZIP

scripts/tests/linting/Invoke-JsonLint.Tests.ps1

190lines · modecode

1#Requires -Modules Pester
2# Copyright (c) Microsoft Corporation.
3# SPDX-License-Identifier: MIT
4<#
5.SYNOPSIS
6 Pester tests for Invoke-JsonLint.ps1 script
7.DESCRIPTION
8 Tests for the strict JSON validator:
9 - Strict parsing of valid and invalid JSON
10 - Detection of trailing commas, comments, and trailing content
11 - File discovery across target paths
12 - CI integration
13#>
14
15BeforeAll {
16 $script:ScriptPath = Join-Path $PSScriptRoot '../../linting/Invoke-JsonLint.ps1'
17 $script:ModulePath = Join-Path $PSScriptRoot '../../linting/Modules/LintingHelpers.psm1'
18 $script:CIHelpersPath = Join-Path $PSScriptRoot '../../lib/Modules/CIHelpers.psm1'
19
20 Import-Module $script:ModulePath -Force
21 Import-Module $script:CIHelpersPath -Force
22
23 . $script:ScriptPath
24
25 $script:TestRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("json-lint-tests-" + [System.Guid]::NewGuid().ToString('N'))
26 New-Item -ItemType Directory -Force -Path $script:TestRoot | Out-Null
27}
28
29AfterAll {
30 if ($script:TestRoot -and (Test-Path $script:TestRoot)) {
31 Remove-Item -Path $script:TestRoot -Recurse -Force -ErrorAction SilentlyContinue
32 }
33 Remove-Module LintingHelpers -Force -ErrorAction SilentlyContinue
34 Remove-Module CIHelpers -Force -ErrorAction SilentlyContinue
35}
36
37#region Test-JsonFile Tests
38
39Describe 'Test-JsonFile' -Tag 'Unit' {
40 BeforeEach {
41 $script:CaseDir = Join-Path $script:TestRoot ([System.Guid]::NewGuid().ToString('N'))
42 New-Item -ItemType Directory -Force -Path $script:CaseDir | Out-Null
43 }
44
45 It 'Returns null for valid JSON' {
46 $file = Join-Path $script:CaseDir 'valid.json'
47 '{ "name": "ok", "values": [1, 2, 3] }' | Set-Content -LiteralPath $file
48 Test-JsonFile -Path $file | Should -BeNullOrEmpty
49 }
50
51 It 'Returns an issue for a trailing comma' {
52 $file = Join-Path $script:CaseDir 'trailing-comma.json'
53 '{ "name": "bad", }' | Set-Content -LiteralPath $file
54 $result = Test-JsonFile -Path $file
55 $result | Should -Not -BeNullOrEmpty
56 $result.File | Should -Be $file
57 }
58
59 It 'Returns an issue for a JSON comment' {
60 $file = Join-Path $script:CaseDir 'comment.json'
61 @'
62{
63 // not allowed
64 "name": "bad"
65}
66'@ | Set-Content -LiteralPath $file
67 Test-JsonFile -Path $file | Should -Not -BeNullOrEmpty
68 }
69
70 It 'Returns an issue for trailing content after the root value' {
71 $file = Join-Path $script:CaseDir 'concat.json'
72 '{ "a": 1 }{ "b": 2 }' | Set-Content -LiteralPath $file
73 Test-JsonFile -Path $file | Should -Not -BeNullOrEmpty
74 }
75
76 It 'Returns an issue for an empty file' {
77 $file = Join-Path $script:CaseDir 'empty.json'
78 '' | Set-Content -LiteralPath $file
79 $result = Test-JsonFile -Path $file
80 $result | Should -Not -BeNullOrEmpty
81 $result.Message | Should -Match 'empty'
82 }
83
84 It 'Reports a positive line number for malformed JSON on a later line' {
85 $file = Join-Path $script:CaseDir 'line.json'
86 @'
87{
88 "a": 1,
89 "b": 2,
90}
91'@ | Set-Content -LiteralPath $file
92 $result = Test-JsonFile -Path $file
93 $result.Line | Should -BeGreaterThan 0
94 }
95}
96
97#endregion Test-JsonFile Tests
98
99#region Invoke-JsonLintCore Tests
100
101Describe 'Invoke-JsonLintCore' -Tag 'Unit' {
102 BeforeEach {
103 Mock Set-CIOutput {}
104 Mock Set-CIEnv {}
105 Mock Write-CIStepSummary {}
106 Mock Write-CIAnnotation {}
107
108 $script:CaseDir = Join-Path $script:TestRoot ([System.Guid]::NewGuid().ToString('N'))
109 New-Item -ItemType Directory -Force -Path $script:CaseDir | Out-Null
110 $script:Output = Join-Path $script:CaseDir 'json-lint-results.json'
111 }
112
113 It 'Does not throw when all JSON files are valid' {
114 '{ "ok": true }' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'a.json')
115 '[1, 2, 3]' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'b.json')
116 { Invoke-JsonLintCore -Paths @($script:CaseDir) -OutputPath $script:Output } | Should -Not -Throw
117 }
118
119 It 'Throws when a JSON file is malformed' {
120 '{ "ok": true }' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'good.json')
121 '{ "bad": true, }' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'bad.json')
122 { Invoke-JsonLintCore -Paths @($script:CaseDir) -OutputPath $script:Output } | Should -Throw
123 }
124
125 It 'Does not throw when there are no JSON files to analyze' {
126 { Invoke-JsonLintCore -Paths @($script:CaseDir) -OutputPath $script:Output } | Should -Not -Throw
127 }
128
129 It 'Skips missing target paths without throwing' {
130 $missing = Join-Path $script:CaseDir 'does-not-exist'
131 { Invoke-JsonLintCore -Paths @($missing) -OutputPath $script:Output } | Should -Not -Throw
132 }
133
134 It 'Accepts a single JSON file as a target path' {
135 $file = Join-Path $script:CaseDir 'single.json'
136 '{ "ok": true }' | Set-Content -LiteralPath $file
137 { Invoke-JsonLintCore -Paths @($file) -OutputPath $script:Output } | Should -Not -Throw
138 }
139
140 It 'Filters changed files to only those under target Paths in ChangedFilesOnly mode' {
141 Mock Get-ChangedFilesFromGit { @('scripts/linting/schemas/a.json', 'docs/x.json') }
142 Mock Test-JsonFile { $null }
143 Invoke-JsonLintCore -Paths @('scripts/linting/schemas') -ChangedFilesOnly -OutputPath $script:Output
144 Assert-MockCalled Test-JsonFile -Times 1 -Exactly -ParameterFilter { $Path -eq 'scripts/linting/schemas/a.json' }
145 Assert-MockCalled Test-JsonFile -Times 0 -Exactly -ParameterFilter { $Path -eq 'docs/x.json' }
146 }
147
148 It 'Creates the OutputPath parent directory when missing' {
149 '{ "ok": true }' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'a.json')
150 $nested = Join-Path $script:CaseDir 'nested/sub/json-lint-results.json'
151 { Invoke-JsonLintCore -Paths @($script:CaseDir) -OutputPath $nested } | Should -Not -Throw
152 Test-Path (Split-Path $nested -Parent) | Should -BeTrue
153 }
154
155 It 'Emits a CI annotation with File and Error level for malformed JSON' {
156 '{ "x": 1, }' | Set-Content -LiteralPath (Join-Path $script:CaseDir 'bad.json')
157 { Invoke-JsonLintCore -Paths @($script:CaseDir) -OutputPath $script:Output } | Should -Throw
158 Assert-MockCalled Write-CIAnnotation -ParameterFilter { $File -like '*bad.json' -and $Level -eq 'Error' }
159 }
160}
161
162#endregion Invoke-JsonLintCore Tests
163
164#region Repository JSON Tests
165
166Describe 'Repository JSON validity' -Tag 'Integration' {
167 It 'All schema and fixture JSON files parse strictly' {
168 $repoRoot = Join-Path $PSScriptRoot '../../..'
169 $targets = @('scripts/linting/schemas', 'scripts/tests/Fixtures') | ForEach-Object {
170 Join-Path $repoRoot $_
171 }
172
173 $failures = @()
174 foreach ($target in $targets) {
175 if (-not (Test-Path $target)) { continue }
176 Get-ChildItem -Path $target -File -Recurse -Filter '*.json' |
177 Where-Object { $_.Name -notlike 'invalid-*.json' } |
178 ForEach-Object {
179 $issue = Test-JsonFile -Path $_.FullName
180 if ($null -ne $issue) {
181 $failures += "$($issue.File): $($issue.Message)"
182 }
183 }
184 }
185
186 $failures | Should -BeNullOrEmpty
187 }
188}
189
190#endregion Repository JSON Tests
191