diff --git a/TestResults/CodeCoverage.html b/TestResults/CodeCoverage.html index 959f318..1db6ad7 100644 --- a/TestResults/CodeCoverage.html +++ b/TestResults/CodeCoverage.html @@ -121,18 +121,20 @@
Watched: 19 fns/opr within #.ZipArchive.ZipArchive
The test suite was executed once:
+The test suite was executed 3 times:
Executed at | APLVersion | Memory (MB) |
---|---|---|
2023-04-09 17:49:24 | Windows-64 ⋄ 18.2.46856.0 ⋄ W ⋄ Development ⋄ Unicode | 52 |
2023-04-09 17:54:45 | Linux-64 ⋄ 18.2.46656.0 ⋄ S ⋄ Development ⋄ Unicode | 246 |
2023-04-09 18:50:51 | Mac-64 ⋄ 18.2.46881.0 ⋄ S ⋄ Development ⋄ Unicode | 248 |
Overall 33% of the testable code is covered.
+Overall 89% of the testable code is covered.
(Comment lines, empty lines, all :End
* lines etc. are ignored)
7 of the fns/opr are 100% covered.
+14 of the fns/opr are 100% covered.
[1] :Access Public Shared
→[2] r←'ZipArchive' '1.0.2+16' '2023-04-09'
#.ZipArchive.ZipArchive.MassageZipConentList — 0%↟↑
- list←MassageZipConentList list
- [1] ⍝ `list`comes from "unzip -l and has a specific contents
-→[2] A←(⊃⊃⎕CLASS ⎕THIS).##.APLTreeUtils2
-→[3] :If 0<≢list←3↓¯2↓list
-→[4] list←' 'A.Split¨A.DMB list
-→[5] list←⊃¨{⍺,' ',⍵}/¨3↓¨list
-→[6] list←('/'≠⊃¨¯1↑¨list)/list
- [7] :EndIf
-#.ZipArchive.ZipArchive.GetHomeDir — 0%↟↑
+#.ZipArchive.ZipArchive.GetHomeDir — 0%↟↑
r←{user}GetHomeDir dummy
[1] ⍝ Get the home directory for a user, by default the current one.
[2] ⍝ You may specify a different user via ⍺.
@@ -282,77 +274,7 @@ →[8] Assert 0=rc
→[9] r←{⍵⊃⍨¯1+≢⍵}':'(≠⊆⊢)⊃msg
#.ZipArchive.ZipArchive.Exec — 0%↟↑
- (rc msg)←Exec cmd
- [1] ⍝ Works out whether "zip" and "unzip" are available at all (all other commands are always available)
-→[2] :Trap 11
-→[3] msg←⎕SH cmd
-→[4] rc←0
- [5] :Else
-→[6] qdmx←⎕DMX
-→[7] rc←,⊃(//)⎕VFI⊃¯1↑' '(≠⊆⊢)msg←qdmx.Message
-→[8] :If (,127)≡rc
-→[9] '"zip" and/or "unzip" not installed'⎕SIGNAL 6
- [10] :EndIf
- [11] :EndTrap
-#.ZipArchive.ZipArchive.ExtractTo — 14%↟↑
- r←names ExtractTo targetFolder
- [1] ⍝ `names` is the name of one or more zipped objects (files or directories)
- [2] ⍝ Those will be extracted into `folder\`.\\
- [3] ⍝ `names` may be simple (single object) or nested (vector of objects).\\
- [4] ⍝ There must be no file or folder of the given name in the target folder, otherwise an error is thrown.\\
- [5] ⍝ `r` is a vector of Booleans with the same lengths as `names`, carrying 1 for success and 0 otherwise.
- [6] ⍝ However, if `names` is or contains the name of a folder, the length of `r` may be smaller than the
- [7] ⍝ number of files and folders extracted.
- [8] ⍝ A typical reason for a failure is that a given file or folder does not exist in the ZIP file.
- [9] :Access Public Instance
- [10] :If IsWindows
- [11] r←names _ZipArchive.ExtractTo targetFolder
- [12] :Else
-→[13] targetFolder←'expand'F.NormalizePath targetFolder
-→[14] list←List
-→[15] folders←∪(⊂'')~⍨{¯1↓1⊃⎕NPARTS ⍵}¨List
-→[16] names←⊆names
-→[17] ('On non-Windows platforms unzipping a folder is not supported yet')Assert 0=+/names∊folders
-→[18] :If 0<+/r←names∊list ⍝,folders
-→[19] names←r/names
-→[20] :If ∨/b←F.Exists(targetFolder,'/')∘,¨names
-→[21] msg←⊃{⍺,';',⍵}/{'The file ''',⍵,''' already exists.'}¨b/names
-→[22] msg ⎕SIGNAL 11
- [23] :EndIf
-→[24] (rc msg)←Exec'cd ',targetFolder,' && unzip ',('expand'F.NormalizePath _filename),∊' "'∘,¨names,¨'"'
-→[25] Assert 0=rc
- [26] :EndIf
- [27] :EndIf
-#.ZipArchive.ZipArchive.make — 24%↟↑
- make(filename overwriteFlag)
- [1] CheckMinVersion ⍬
- [2] _filename←AddExtension filename
- [3] :If IsWindows
- [4] _ZipArchive←⎕NEW(⊃⊃⎕CLASS ⎕THIS).##.DotNetZip(_filename overwriteFlag)
- [5] :Else
-→[6] :If '~/'≡2↑_filename
-→[7] _filename←(GetHomeDir ⍬),1↓_filename
- [8] :EndIf
-→[9] F←(⊃⊃⎕CLASS ⎕THIS).##.FilesAndDirs
-→[10] 'Must not be a directory'Assert~F.IsDir _filename
-→[11] :If overwriteFlag
-→[12] F.DeleteFile _filename
- [13] :EndIf
-→[14] :If ~F.IsFile _filename
-→[15] tempFilename←F.GetTempFilename2''
-→[16] (rc msg)←Exec'zip ',_filename,' ',tempFilename,' -q'
-→[17] Assert 0=rc
-→[18] (rc msg)←Exec'zip ',_filename,' ',tempFilename,' -dq'
-→[19] Assert 0=rc
-→[20] {}Exec'rm ',tempFilename,' -f'
- [21] :EndIf
- [22] :EndIf
- [23] ⍝Done
-#.ZipArchive.ZipArchive.UnzipTo — 27%↟↑
+#.ZipArchive.ZipArchive.UnzipTo — 67%↟↑
{r}←zipFilename UnzipTo targetFolder
[1] ⍝ Unzip `⍵` into `⍺`.\\
[2] ⍝ `targetFolder` must not yet exist.
@@ -362,27 +284,105 @@ [6] :If IsWindows
[7] {}zipFilename ##.DotNetZip.UnzipTo targetFolder
[8] :Else
-→[9] zipFilename←F.EnforceSlash AddExtension zipFilename
+ [9] zipFilename←F.EnforceSlash AddExtension zipFilename
[10] ⍝ For unknown reasons the following statement tends to crash, yet the unzip utility unzips everything anyway,
[11] ⍝ therefore we trap the error and just compare the number of files in the archive with what we've got.
-→[12] :Trap 11
-→[13] (rc msg)←Exec'unzip -o -qq "',(zipFilename~'"'),'"',(0<≢targetFolder)/' -d "',(targetFolder~'"'),'"'
+ [12] :Trap 11
+ [13] (rc msg)←Exec'unzip -o -qq "',(zipFilename~'"'),'"',(0<≢targetFolder)/' -d "',(targetFolder~'"'),'"'
[14] :Else
→[15] qdmx←⎕DMX
→[16] qdmx.Message ⎕SIGNAL qdmx.EN
[17] :EndTrap
-→[18] :If rc≠0
+ [18] :If rc≠0
→[19] :If rc≠2
→[20] :OrIf ~(ListZipContents zipFilename){(∧/⍺∊⍵)∧∧/⍵∊⍺}(1+≢targetFolder)↓¨⊃F.Dir targetFolder,'/*'
→[21] msg Assert 0=rc
[22] :EndIf
[23] :EndIf
[24] ⍝ On my Ubuntu VM under Hyper-V I get files and dirs with no priviliges, so defaults need to be established:
-→[25] {}{Exec'chmod 666 "',⍵,'"'}EachIfNotEmpty'recursive'F.ListFiles targetFolder,'/'
-→[26] {}{Exec'chmod 777 "',⍵,'"'}EachIfNotEmpty'recursive'F.ListDirs targetFolder,'/'
+ [25] {}{Exec'chmod 666 "',⍵,'"'}EachIfNotEmpty'recursive'F.ListFiles targetFolder,'/'
+ [26] {}{Exec'chmod 777 "',⍵,'"'}EachIfNotEmpty'recursive'F.ListDirs targetFolder,'/'
[27] :EndIf
#.ZipArchive.ZipArchive.Add — 38%↟↑
+#.ZipArchive.ZipArchive.Exec — 86%↟↑
+ (rc msg)←Exec cmd
+ [1] ⍝ Works out whether "zip" and "unzip" are available at all (all other commands are always available)
+ [2] :Trap 11
+ [3] msg←⎕SH cmd
+ [4] rc←0
+ [5] :Else
+ [6] qdmx←⎕DMX
+ [7] rc←,⊃(//)⎕VFI⊃¯1↑' '(≠⊆⊢)msg←qdmx.Message
+ [8] :If (,127)≡rc
+→[9] '"zip" and/or "unzip" not installed'⎕SIGNAL 6
+ [10] :EndIf
+ [11] :EndTrap
+#.ZipArchive.ZipArchive.make — 94%↟↑
+ make(filename overwriteFlag)
+ [1] CheckMinVersion ⍬
+ [2] _filename←AddExtension filename
+ [3] :If IsWindows
+ [4] _ZipArchive←⎕NEW(⊃⊃⎕CLASS ⎕THIS).##.DotNetZip(_filename overwriteFlag)
+ [5] :Else
+ [6] :If '~/'≡2↑_filename
+→[7] _filename←(GetHomeDir ⍬),1↓_filename
+ [8] :EndIf
+ [9] F←(⊃⊃⎕CLASS ⎕THIS).##.FilesAndDirs
+ [10] 'Must not be a directory'Assert~F.IsDir _filename
+ [11] :If overwriteFlag
+ [12] F.DeleteFile _filename
+ [13] :EndIf
+ [14] :If ~F.IsFile _filename
+ [15] tempFilename←F.GetTempFilename2''
+ [16] (rc msg)←Exec'zip ',_filename,' ',tempFilename,' -q'
+ [17] Assert 0=rc
+ [18] (rc msg)←Exec'zip ',_filename,' ',tempFilename,' -dq'
+ [19] Assert 0=rc
+ [20] {}Exec'rm ',tempFilename,' -f'
+ [21] :EndIf
+ [22] :EndIf
+ [23] ⍝Done
+#.ZipArchive.ZipArchive.set_filename — 100%↟↑
+#.ZipArchive.ZipArchive.get_filename — 100%↟↑
+ r←get_filename
+ [1] r←_filename
+#.ZipArchive.ZipArchive.History — 100%↟↑
+ History
+ [1] :Access Public Shared
+ [2] ⍝ * 1.0.2 from 2023-04-09
+ [3] ⍝ * Bug fix in `UnzipTo`: issues with spaces in filenames on non-Windows platforms
+ [4] ⍝ * 1.0.1 from 2023-02-06
+ [5] ⍝ * `UnzipTo` is more resilient under Linux now
+ [6] ⍝ * 1.0.0 from 2022-06-13
+ [7] ⍝ * First version ready for production
+#.ZipArchive.ZipArchive.make1 — 100%↟↑
+ make1(filename)
+ [1] ⍝ Constructor that takes just one argument: the name of the ZIP file.\\
+ [2] ⍝ If `zipFilename` already exists it is opened.
+ [3] :Access Public instance
+ [4] :Implements Constructor
+ [5] overwriteFlag←0
+ [6] make filename overwriteFlag
+ [7] ⍝Done
+#.ZipArchive.ZipArchive.make2 — 100%↟↑
+ make2(zipFilename overwriteFlag)
+ [1] ⍝ Constructor that takes two arguments:
+ [2] ⍝ * the name of the ZIP file
+ [3] ⍝ * Boolean for `overwriteFlag`\\
+ [4] ⍝ `overwriteFlag` is used to determine whether the ZIP should be opened (0=default)
+ [5] ⍝ or overwritten (1).
+ [6] :Access Public Instance
+ [7] :Implements Constructor
+ [8] '"overwriteFlag" must be a Boolean'⎕SIGNAL 11/⍨~(⊂overwriteFlag)∊0 1
+ [9] make zipFilename overwriteFlag
+#.ZipArchive.ZipArchive.Add — 100%↟↑
{r}←{parent}Add toBeZipped
[1] ⍝ Use this to add one or more files to the ZIP file.\\
[2] ⍝ `toBeZipped` specifies the full path (or full paths) of what's going to be zipped. That's what's going to be
@@ -409,19 +409,32 @@ [23] res←parent _ZipArchive.Add toBeZipped
[24] :EndIf
[25] :Else
-→[26] toBeZipped←F.NormalizePath toBeZipped
-→[27] :If 0=⎕NC'parent'
-→[28] (rc msg)←Exec'zip -r ',_filename,' ',∊'"',¨(⊆toBeZipped),¨⊂'" '
-→[29] Assert 0=rc
+ [26] toBeZipped←F.NormalizePath toBeZipped
+ [27] :If 0=⎕NC'parent'
+ [28] (rc msg)←Exec'zip -r ',_filename,' ',∊'"',¨(⊆toBeZipped),¨⊂'" '
+ [29] Assert 0=rc
[30] :Else
-→[31] parent←'expand'F.NormalizePath parent
-→[32] toBeZipped←{⍵↓⍨'/'=1⍴⍵}¨⊆toBeZipped
-→[33] (rc msg)←Exec'cd ',parent,' && zip -r "',('expand'F.NormalizePath _filename~'"'),'" ',∊' ',¨'"',¨(toBeZipped~¨'"'),¨'"'
-→[34] Assert 0=rc
+ [31] parent←'expand'F.NormalizePath parent
+ [32] toBeZipped←{⍵↓⍨'/'=1⍴⍵}¨⊆toBeZipped
+ [33] (rc msg)←Exec'cd ',parent,' && zip -r "',('expand'F.NormalizePath _filename~'"'),'" ',∊' ',¨'"',¨(toBeZipped~¨'"'),¨'"'
+ [34] Assert 0=rc
[35] :EndIf
[36] :EndIf
#.ZipArchive.ZipArchive.Delete — 43%↟↑
+#.ZipArchive.ZipArchive.List — 100%↟↑
+ r←List
+ [1] ⍝ Lists the contents of the ZIP file.
+ [2] :Access Public Instance
+ [3] :If IsWindows
+ [4] r←_ZipArchive.List
+ [5] r←{'.//'≡3⍴⍵:'./',3↓⍵ ⋄ '.\\'≡3⍴⍵:'.\',3↓⍵ ⋄ ⍵}¨r
+ [6] :Else
+ [7] (rc msg)←Exec'unzip -l ',_filename
+ [8] Assert 0=rc
+ [9] r←MassageZipConentList msg
+ [10] :EndIf
+#.ZipArchive.ZipArchive.Delete — 100%↟↑
{r}←Delete filenames
[1] ⍝ Delete one or more files from the ZIP.\\
[2] ⍝ Returns `⍬` (shy).
@@ -430,27 +443,55 @@ [5] :If IsWindows
[6] {}_ZipArchive.Delete filenames
[7] :Else
-→[8] filenames←F.NormalizePath⊆filenames
-→[9] :If 0<≢filenames←(filenames∊List)/filenames
-→[10] (rc msg)←Exec'zip -d ',_filename,∊' ',¨'"',¨filenames,¨'"'
-→[11] Assert 0=rc
+ [8] filenames←F.NormalizePath⊆filenames
+ [9] :If 0<≢filenames←(filenames∊List)/filenames
+ [10] (rc msg)←Exec'zip -d ',_filename,∊' ',¨'"',¨filenames,¨'"'
+ [11] Assert 0=rc
[12] :EndIf
[13] :EndIf
#.ZipArchive.ZipArchive.List — 50%↟↑
- r←List
- [1] ⍝ Lists the contents of the ZIP file.
- [2] :Access Public Instance
- [3] :If IsWindows
- [4] r←_ZipArchive.List
- [5] r←{'.//'≡3⍴⍵:'./',3↓⍵ ⋄ '.\\'≡3⍴⍵:'.\',3↓⍵ ⋄ ⍵}¨r
- [6] :Else
-→[7] (rc msg)←Exec'unzip -l ',_filename
-→[8] Assert 0=rc
-→[9] r←MassageZipConentList msg
- [10] :EndIf
+#.ZipArchive.ZipArchive.ExtractTo — 100%↟↑
+ r←names ExtractTo targetFolder
+ [1] ⍝ `names` is the name of one or more zipped objects (files or directories)
+ [2] ⍝ Those will be extracted into `folder\`.\\
+ [3] ⍝ `names` may be simple (single object) or nested (vector of objects).\\
+ [4] ⍝ There must be no file or folder of the given name in the target folder, otherwise an error is thrown.\\
+ [5] ⍝ `r` is a vector of Booleans with the same lengths as `names`, carrying 1 for success and 0 otherwise.
+ [6] ⍝ However, if `names` is or contains the name of a folder, the length of `r` may be smaller than the
+ [7] ⍝ number of files and folders extracted.
+ [8] ⍝ A typical reason for a failure is that a given file or folder does not exist in the ZIP file.
+ [9] :Access Public Instance
+ [10] :If IsWindows
+ [11] r←names _ZipArchive.ExtractTo targetFolder
+ [12] :Else
+ [13] targetFolder←'expand'F.NormalizePath targetFolder
+ [14] list←List
+ [15] folders←∪(⊂'')~⍨{¯1↓1⊃⎕NPARTS ⍵}¨List
+ [16] names←⊆names
+ [17] ('On non-Windows platforms unzipping a folder is not supported yet')Assert 0=+/names∊folders
+ [18] :If 0<+/r←names∊list ⍝,folders
+ [19] names←r/names
+ [20] :If ∨/b←F.Exists(targetFolder,'/')∘,¨names
+ [21] msg←⊃{⍺,';',⍵}/{'The file ''',⍵,''' already exists.'}¨b/names
+ [22] msg ⎕SIGNAL 11
+ [23] :EndIf
+ [24] (rc msg)←Exec'cd ',targetFolder,' && unzip ',('expand'F.NormalizePath _filename),∊' "'∘,¨names,¨'"'
+ [25] Assert 0=rc
+ [26] :EndIf
+ [27] :EndIf
+#.ZipArchive.ZipArchive.Dispose — 100%↟↑
+ Dispose
+ [1] ⍝ Use this to close the `ZipArchive` instance.\\
+ [2] ⍝ Note that deleteting a instance of `ZipArchive` has the same effect as calling this method although the timing might differ
+ [3] :Access Public Instance
+ [4] :If IsWindows
+ [5] _ZipArchive.Dispose
+ [6] :Else
+ [7] ⍝ Nothing to do here
+ [8] :EndIf
#.ZipArchive.ZipArchive.ZipFolder — 50%↟↑
+#.ZipArchive.ZipArchive.ZipFolder — 100%↟↑
zipFilename←sourceFolder ZipFolder zipFilename
[1] ⍝ Takes a folder and zips it. `zipFilename` must not exist.\\
[2] ⍝ Returns the fully expanded name of `zipFilename`.\\
@@ -462,12 +503,12 @@ [8] :If IsWindows
[9] zipFilename←sourceFolder ##.DotNetZip.ZipFolder zipFilename
[10] :Else
-→[11] zipFilename←AddExtension zipFilename
-→[12] ('Is not a directory: ',sourceFolder)Assert(⊃⊃⎕CLASS ⎕THIS).##.FilesAndDirs.IsDir sourceFolder
-→[13] res←Exec'cd ',('expand'F.NormalizePath sourceFolder),' && zip -r ',zipFilename,' *'
+ [11] zipFilename←AddExtension zipFilename
+ [12] ('Is not a directory: ',sourceFolder)Assert(⊃⊃⎕CLASS ⎕THIS).##.FilesAndDirs.IsDir sourceFolder
+ [13] res←Exec'cd ',('expand'F.NormalizePath sourceFolder),' && zip -r ',zipFilename,' *'
[14] :EndIf
#.ZipArchive.ZipArchive.ListZipContents — 56%↟↑
+#.ZipArchive.ZipArchive.ListZipContents — 100%↟↑
r←ListZipContents zipFilename
[1] ⍝ List the contents of a ZIP file
[2] :Access Public Shared
@@ -477,60 +518,21 @@ [6] r←instance.List
[7] instance.Dispose
[8] :Else
-→[9] zipFilename←AddExtension zipFilename
-→[10] (rc msg)←Exec'unzip -l ',zipFilename
-→[11] Assert 0=rc
-→[12] r←MassageZipConentList msg
+ [9] zipFilename←AddExtension zipFilename
+ [10] (rc msg)←Exec'unzip -l ',zipFilename
+ [11] Assert 0=rc
+ [12] r←MassageZipConentList msg
[13] :EndIf
#.ZipArchive.ZipArchive.set_filename — 100%↟↑
-#.ZipArchive.ZipArchive.get_filename — 100%↟↑
- r←get_filename
- [1] r←_filename
-#.ZipArchive.ZipArchive.History — 100%↟↑
- History
- [1] :Access Public Shared
- [2] ⍝ * 1.0.2 from 2023-04-09
- [3] ⍝ * Bug fix in `UnzipTo`: issues with spaces in filenames on non-Windows platforms
- [4] ⍝ * 1.0.1 from 2023-02-06
- [5] ⍝ * `UnzipTo` is more resilient under Linux now
- [6] ⍝ * 1.0.0 from 2022-06-13
- [7] ⍝ * First version ready for production
-#.ZipArchive.ZipArchive.make1 — 100%↟↑
- make1(filename)
- [1] ⍝ Constructor that takes just one argument: the name of the ZIP file.\\
- [2] ⍝ If `zipFilename` already exists it is opened.
- [3] :Access Public instance
- [4] :Implements Constructor
- [5] overwriteFlag←0
- [6] make filename overwriteFlag
- [7] ⍝Done
-#.ZipArchive.ZipArchive.make2 — 100%↟↑
- make2(zipFilename overwriteFlag)
- [1] ⍝ Constructor that takes two arguments:
- [2] ⍝ * the name of the ZIP file
- [3] ⍝ * Boolean for `overwriteFlag`\\
- [4] ⍝ `overwriteFlag` is used to determine whether the ZIP should be opened (0=default)
- [5] ⍝ or overwritten (1).
- [6] :Access Public Instance
- [7] :Implements Constructor
- [8] '"overwriteFlag" must be a Boolean'⎕SIGNAL 11/⍨~(⊂overwriteFlag)∊0 1
- [9] make zipFilename overwriteFlag
-#.ZipArchive.ZipArchive.Dispose — 100%↟↑
- Dispose
- [1] ⍝ Use this to close the `ZipArchive` instance.\\
- [2] ⍝ Note that deleteting a instance of `ZipArchive` has the same effect as calling this method although the timing might differ
- [3] :Access Public Instance
- [4] :If IsWindows
- [5] _ZipArchive.Dispose
- [6] :Else
- [7] ⍝ Nothing to do here
- [8] :EndIf
+#.ZipArchive.ZipArchive.MassageZipConentList — 100%↟↑
+ list←MassageZipConentList list
+ [1] ⍝ `list`comes from "unzip -l and has a specific contents
+ [2] A←(⊃⊃⎕CLASS ⎕THIS).##.APLTreeUtils2
+ [3] :If 0<≢list←3↓¯2↓list
+ [4] list←' 'A.Split¨A.DMB list
+ [5] list←⊃¨{⍺,' ',⍵}/¨3↓¨list
+ [6] list←('/'≠⊃¨¯1↑¨list)/list
+ [7] :EndIf
#.ZipArchive.ZipArchive.IsWindows — 100%↟↑
r←IsWindows
diff --git a/TestResults/CodeCoverage.profile b/TestResults/CodeCoverage.profile
index 8fe85f7..a25d4a2 100644
Binary files a/TestResults/CodeCoverage.profile and b/TestResults/CodeCoverage.profile differ