Repository: MaxDesiatov/CoreXLSX (swift)

Issue:
archiveEntryNotFound error
**Version**

0.12.0

**Description of the bug**

An `archiveEntryNotFound` error is thrown for certain files (but I couldn't figure out what exactly causes the issue)

**Steps to reproduce**

1. Load the file attached bellow (`let file = XLSXFile(filepath: tableFilePath)`)
2. Call `parseSharedStrings`

**File for reproduction**

Test.xlsx
https://tools.hb.bizmrg.com/Test.xlsx

Pull request:
Resolves #121.

Patch:
diff --git a/README.md b/README.md
index 0024d730..715700a2 100644
--- a/README.md
+++ b/README.md
@@ -73,9 +73,10 @@ use of `stringValue(_: SharedStrings)` function is recommended together with
 Here's how you can get all strings in column "C" for example:
 
 ```swift
-let sharedStrings = try file.parseSharedStrings()
-let columnCStrings = worksheet.cells(atColumns: [ColumnReference("C")!])
-  .compactMap { $0.stringValue(sharedStrings) }
+if let sharedStrings = try file.parseSharedStrings() {
+  let columnCStrings = worksheet.cells(atColumns: [ColumnReference("C")!])
+    .compactMap { $0.stringValue(sharedStrings) }
+}
 ```
 
 To parse a date value from a cell, use `dateValue` property on the `Cell` type:
@@ -88,9 +89,10 @@ let columnCDates = worksheet.cells(atColumns: [ColumnReference("C")!])
 Similarly, to parse rich strings, use the `richStringValue` function:
 
 ```swift
-let richStrings = try file.parseSharedStrings()
-let columnCRichStrings = worksheet.cells(atColumns: [ColumnReference("C")!])
-  .compactMap { $0.richStringValue(sharedStrings) }
+if let richStrings = try file.parseSharedStrings() {
+  let columnCRichStrings = worksheet.cells(atColumns: [ColumnReference("C")!])
+    .compactMap { $0.richStringValue(sharedStrings) }
+}
 ```
 
 ### Styles
diff --git a/Sources/CoreXLSX/XLSXFile.swift b/Sources/CoreXLSX/XLSXFile.swift
index 9bbbcdc2..f15714a4 100644
--- a/Sources/CoreXLSX/XLSXFile.swift
+++ b/Sources/CoreXLSX/XLSXFile.swift
@@ -138,10 +138,14 @@ public class XLSXFile {
     return try parseEntry("xl/styles.xml", Styles.self)
   }
 
-  public func parseSharedStrings() throws -> SharedStrings {
+  public func parseSharedStrings() throws -> SharedStrings? {
     decoder.keyDecodingStrategy = .useDefaultKeys
 
-    return try parseEntry("xl/sharedStrings.xml", SharedStrings.self)
+    do {
+      return try parseEntry("xl/sharedStrings.xml", SharedStrings.self)
+    } catch CoreXLSXError.archiveEntryNotFound {
+      return nil
+    }
   }
 
   private func buildCommentsPath(forWorksheet path: String) throws -> String {


Test patch:
diff --git a/Tests/CoreXLSXTests/CellReference.swift b/Tests/CoreXLSXTests/CellReference.swift
index 54a89ca4..f01fd888 100644
--- a/Tests/CoreXLSXTests/CellReference.swift
+++ b/Tests/CoreXLSXTests/CellReference.swift
@@ -78,7 +78,7 @@ final class CellReferenceTests: XCTestCase {
     XCTAssertNotEqual(ColumnReference("A"), ColumnReference("B"))
 
     guard let a = ColumnReference("A"), let b = ColumnReference("B") else {
-      XCTAssert(false, "failed to create simple column references")
+      XCTFail("failed to create simple column references")
       return
     }
 
@@ -91,7 +91,7 @@ final class CellReferenceTests: XCTestCase {
     guard let a = ColumnReference("A"), let z = ColumnReference("z"),
       let aa = ColumnReference("AA"), let az = ColumnReference("Az"),
       let ba = ColumnReference("ba"), let bz = ColumnReference("bz") else {
-      XCTAssert(false, "failed to create simple column references")
+      XCTFail("failed to create simple column references")
       return
     }
     let alphabetLength = 26
@@ -114,7 +114,7 @@ final class CellReferenceTests: XCTestCase {
       let ba = ColumnReference("ba"), let bz = ColumnReference("bz"),
       let abc = ColumnReference("abc"), let azz = ColumnReference("azz"),
       let zz = ColumnReference("zz"), let azza = ColumnReference("azza") else {
-      XCTAssert(false, "failed to create simple column references")
+      XCTFail("failed to create simple column references")
       return
     }
 
@@ -148,7 +148,7 @@ final class CellReferenceTests: XCTestCase {
 
   func testColumnReferenceAdvancedBy() {
     guard let a = ColumnReference("A"), let bz = ColumnReference("bz") else {
-      XCTAssert(false, "failed to create simple column references")
+      XCTFail("failed to create simple column references")
       return
     }
 
diff --git a/Tests/CoreXLSXTests/Comments.swift b/Tests/CoreXLSXTests/Comments.swift
index 8b8aaca9..182d2d7c 100644
--- a/Tests/CoreXLSXTests/Comments.swift
+++ b/Tests/CoreXLSXTests/Comments.swift
@@ -19,7 +19,7 @@ final class CommentsTests: XCTestCase {
   func testComments() throws {
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/comments.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
     let paths = try file.parseWorksheetPaths()
diff --git a/Tests/CoreXLSXTests/Relationships.swift b/Tests/CoreXLSXTests/Relationships.swift
index 57137fc4..5cb997c7 100644
--- a/Tests/CoreXLSXTests/Relationships.swift
+++ b/Tests/CoreXLSXTests/Relationships.swift
@@ -83,7 +83,7 @@ final class RelationshipsTests: XCTestCase {
 
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
 
@@ -103,7 +103,7 @@ final class RelationshipsTests: XCTestCase {
   func testCustomXmlSchemaType() throws {
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/jewelershealthcare.com-census.1.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
 
diff --git a/Tests/CoreXLSXTests/SharedStrings.swift b/Tests/CoreXLSXTests/SharedStrings.swift
index b618ffc9..e974b3b5 100644
--- a/Tests/CoreXLSXTests/SharedStrings.swift
+++ b/Tests/CoreXLSXTests/SharedStrings.swift
@@ -91,14 +91,14 @@ private let richTextXML = """
 
 final class SharedStringsTests: XCTestCase {
   func testSharedStrings() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard
+      let file = XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx"),
+      let sharedStrings = try file.parseSharedStrings()
+    else {
+      XCTFail("failed to open the file and get access to its shared strings")
       return
     }
 
-    let sharedStrings = try file.parseSharedStrings()
-
     // check each individual item so that it's easier to debug when something
     // goes wrong
     for (i, item) in sharedStrings.items.enumerated() {
@@ -110,14 +110,14 @@ final class SharedStringsTests: XCTestCase {
   }
 
   func testSharedStringsOrder() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard
+      let file = XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx"),
+      let sharedStrings = try file.parseSharedStrings()
+    else {
+      XCTFail("failed to open the file and get access to its shared strings")
       return
     }
 
-    let sharedStrings = try file.parseSharedStrings()
-
     var columnCStrings: [String] = []
 
     for path in try file.parseWorksheetPaths() {
diff --git a/Tests/CoreXLSXTests/Styles.swift b/Tests/CoreXLSXTests/Styles.swift
index 03b7e3e2..8f382800 100644
--- a/Tests/CoreXLSXTests/Styles.swift
+++ b/Tests/CoreXLSXTests/Styles.swift
@@ -89,7 +89,7 @@ final class StylesTests: XCTestCase {
   func testStyles() throws {
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
 
diff --git a/Tests/CoreXLSXTests/Workbook.swift b/Tests/CoreXLSXTests/Workbook.swift
index fd9eed33..bac82007 100644
--- a/Tests/CoreXLSXTests/Workbook.swift
+++ b/Tests/CoreXLSXTests/Workbook.swift
@@ -51,7 +51,7 @@ final class WorkbookTests: XCTestCase {
   func testWorkbook() throws {
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
 
@@ -62,7 +62,7 @@ final class WorkbookTests: XCTestCase {
   func testWorksheetPathsAndNames() throws {
     guard let file =
       XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+      XCTFail("failed to open the file")
       return
     }
 
diff --git a/Tests/CoreXLSXTests/XLSXFile.swift b/Tests/CoreXLSXTests/XLSXFile.swift
index aa11e8b7..5f39e406 100644
--- a/Tests/CoreXLSXTests/XLSXFile.swift
+++ b/Tests/CoreXLSXTests/XLSXFile.swift
@@ -15,9 +15,9 @@ final class CoreXLSXTests: XCTestCase {
   private let sheetPath = "xl/worksheets/sheet1.xml"
 
   func testBlank() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/Blank.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard let file = XLSXFile(filepath: "\(currentWorkingPath)/Blank.xlsx")
+    else {
+      XCTFail("failed to open the file")
       return
     }
 
@@ -31,9 +31,9 @@ final class CoreXLSXTests: XCTestCase {
   }
 
   func testHelloWorld() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/HelloWorld.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard let file = XLSXFile(filepath: "\(currentWorkingPath)/HelloWorld.xlsx")
+    else {
+      XCTFail("failed to open the file")
       return
     }
 
@@ -47,13 +47,14 @@ final class CoreXLSXTests: XCTestCase {
   }
 
   func testMultiline() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/multi-line.text.in.cell.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard
+      let file = XLSXFile(filepath: "\(currentWorkingPath)/multi-line.text.in.cell.xlsx"),
+      let strings = try file.parseSharedStrings()
+    else {
+      XCTFail("failed to open the file and get access to its shared strings")
       return
     }
 
-    let strings = try file.parseSharedStrings()
     XCTAssertEqual(strings.uniqueCount, 2)
     XCTAssertEqual(strings.items, [
       .init(text: "just a single line", richText: []),
@@ -69,9 +70,8 @@ final class CoreXLSXTests: XCTestCase {
   }
 
   func testDates() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/Dates.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard let file = XLSXFile(filepath: "\(currentWorkingPath)/Dates.xlsx") else {
+      XCTFail("failed to open the file")
       return
     }
 
@@ -99,9 +99,11 @@ final class CoreXLSXTests: XCTestCase {
   }
 
   func testPublicAPI() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard
+      let file = XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx"),
+      let strings = try file.parseSharedStrings()
+    else {
+      XCTFail("failed to open the file and get access to its shared strings")
       return
     }
 
@@ -110,7 +112,7 @@ final class CoreXLSXTests: XCTestCase {
 
     let ws = try file.parseWorksheet(at: sheetPath)
     guard let sd = ws.data else {
-      XCTAssert(false, "no sheet data available")
+      XCTFail("no sheet data available")
       return
     }
     let allCells = sd.rows
@@ -141,14 +143,13 @@ final class CoreXLSXTests: XCTestCase {
     let cellsInRange = ws.cells(atColumns: closedRange2, rows: rowsRange)
     XCTAssertEqual(cellsInRange.count, closedRange2.count * rowsRange.count)
 
-    let strings = try file.parseSharedStrings()
     XCTAssertEqual(strings.items.count, 18)
   }
 
   func testLegacyPublicAPI() throws {
-    guard let file =
-      XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx") else {
-      XCTAssert(false, "failed to open the file")
+    guard let file = XLSXFile(filepath: "\(currentWorkingPath)/categories.xlsx")
+    else {
+      XCTFail("failed to open the file")
       return
     }
 
@@ -173,7 +174,7 @@ final class CoreXLSXTests: XCTestCase {
     XCTAssertEqual(ws.dimension?.ref, ws.dimension?.reference)
 
     guard let mcs = ws.mergeCells else {
-      XCTAssert(false, "expected to parse merge cells from categories.xlsx")
+      XCTFail("expected to parse merge cells from categories.xlsx")
       return
     }
     for mc in mcs.items {