-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathShould-BeZipArchiveOnlyContaining.psm1
More file actions
148 lines (121 loc) · 5.03 KB
/
Copy pathShould-BeZipArchiveOnlyContaining.psm1
File metadata and controls
148 lines (121 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
function Should-BeZipArchiveOnlyContaining {
<#
.SYNOPSIS
Checks if a zip archive contains the entries $ExpectedValue
.EXAMPLE
"C:\Users\<user>\archive.zip" | Should -BeZipArchiveContaining @("file1.txt")
Checks if archive.zip only contains file1.txt
#>
[CmdletBinding()]
Param (
[string] $ActualValue,
[string[]] $ExpectedValue,
[switch] $Negate,
[string] $Because,
[switch] $LiteralPath,
$CallerSessionState
)
# ActualValue is supposed to be a path to an archive
# It could be a path to a custom PSDrive, so it needes to be converted
if ($LiteralPath) {
$ActualValue = Convert-Path -LiteralPath $ActualValue
} else {
$ActualValue = Convert-Path -Path $ActualValue
}
# Ensure ActualValue is a valid path
if ($LiteralPath) {
$testPathResult = Test-Path -LiteralPath $ActualValue
} else {
$testPathResult = Test-Path -Path $ActualValue
}
# Don't continue processing if ActualValue is not an actual path
# Determine if the assertion succeeded or failed and then return
if (-not $testPathResult) {
$succeeded = $Negate
if (-not $succeeded) {
$failureMessage = "The path ${ActualValue} does not exist"
}
return [pscustomobject]@{
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
# Get 7-zip to list the contents of the archive
if ($IsWindows) {
$output = 7z.exe l $ActualValue -ba -tzip
} else {
$output = 7z l $ActualValue -ba -tzip
}
# Check if the output is null
if ($null -eq $output) {
if ($null -eq $ExpectedValue -or $ExpectedValue.Length -eq 0) {
$succeeded = -not $Negate
} else {
$succeeded = $Negate
}
if (-not $succeeded) {
$failureMessage = "Archive {0} contains nothing, but it was expected to contain something"
}
return [pscustomobject]@{
Succeeded = $succeeded
FailureMessage = $failureMessage
}
}
# Filter the output line by line
$lines = $output -split [System.Environment]::NewLine
# Stores the entry names
$entryNames = @()
# Go through each line and split it by whitespace
foreach ($line in $lines) {
$lineComponents = $line -split " +"
# Example of some lines:
#2022-08-05 15:54:04 D.... 0 0 SourceDir
#2022-08-05 15:54:04 ..... 11 11 SourceDir/Sample-1.txt
# First component is date
# 2nd component is time
# 3rd componnent is attributes
# 4th component is size
# 5th component is compressed size
# 6th component is entry name
$entryName = $lineComponents[$lineComponents.Length - 1]
# Since 7zip does not show trailing forwardslash for directories, we need to check the attributes to see if it starts with 'D'
# If so, it means the entry is a directory and we should append a forwardslash to the entry name
if ($lineComponents[2].StartsWith('D')) {
$entryName += '/'
}
# Replace backslashes to forwardslashes
$dirSeperatorChar = [System.IO.Path]::DirectorySeparatorChar
$entryName = $entryName.Replace($dirSeperatorChar, "/")
$entryNames += $entryName
}
$itemsNotInArchive = @()
# Go through each item in ExpectedValue and ensure it is in entryNames
foreach ($expectedItem in $ExpectedValue) {
if ($entryNames -notcontains $expectedItem) {
$itemsNotInArchive += $expectedItem
}
}
if ($itemsNotInArchive.Length -gt 0 -and -not $Negate) {
# Create a comma-seperated string from $itemsNotInEnryName
$commaSeperatedItemsNotInArchive = $itemsNotInArchive -join ","
$failureMessage = "'$ActualValue' does not contain $commaSeperatedItemsNotInArchive $(if($Because) { "because $Because"})."
$succeeded = $false
}
# Ensure the length of $entryNames is equal to that of $ExpectedValue
if ($null -eq $succeeded -and $entryNames.Length -ne $ExpectedValue.Length -and -not $Negate) {
$failureMessage = "${ActualValue} does not contain the same number of items as ${ExpectedValue -join ""} (expected ${ExpectedValue.Length} entries but found ${entryNames.Length}) $(if($Because) { "because $Because"})."
$succeeded = $false
}
if ($null -eq $succeeded) {
$succeeded = -not $Negate
if (-not $succeeded) {
$failureMessage = "Expected ${ActualValue} to not contain the entries ${ExpectedValue -join ""} only $(if($Because) { "because $Because"})."
}
}
$ObjProperties = @{
Succeeded = $succeeded
FailureMessage = $failureMessage
}
return New-Object PSObject -Property $ObjProperties
}
Add-ShouldOperator -Name BeZipArchiveOnlyContaining -InternalName 'Should-BeZipArchiveOnlyContaining' -Test ${function:Should-BeZipArchiveOnlyContaining}