File: FolderStructure.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (135 lines) | stat: -rw-r--r-- 6,667 bytes parent folder | download
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
/*
 This source file is part of the Swift.org open source project

 Copyright (c) 2021-2024 Apple Inc. and the Swift project authors
 Licensed under Apache License v2.0 with Runtime Library Exception

 See https://swift.org/LICENSE.txt for license information
 See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

@testable import SwiftDocC
@testable import SwiftDocCUtilities
import XCTest
import SwiftDocCTestUtilities

/*
 This file contains a test helper API for working with folder hierarchies, with the ability to:
 
  1. write a hierarchy of folders and files to disk
  2. verify that a hierarchy of folders and files exist on disk
*/

protocol AssertableFile: File {
    /// Asserts that a file exist a given URL.
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString, line: UInt) // Implement this since protocol methods can't have default arguments.
}

extension AssertableFile {
    /// Asserts that a file exist a given URL.
    func assertExist(at location: URL, fileManager: FileManagerProtocol = FileManager.default, file: StaticString = #file, line: UInt = #line) {
        __assertExist(at: location, fileManager: fileManager, file: (file), line: line)
    }
}

extension AssertableFile {
    /// Writes the file inside of a folder and returns the URL that it was written to.
    func write(inside url: URL) throws -> URL {
        let outputURL = url.appendingPathComponent(name)
        try write(to: outputURL)
        return outputURL
    }
}

// MARK: -

extension Folder: AssertableFile {
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString = #file, line: UInt = #line) {
        var isFolder: ObjCBool = false
        XCTAssert(fileManager.fileExists(atPath: location.path, isDirectory: &isFolder),
                  "Folder '\(name)' should exist at '\(location.path)'", file: (file), line: line)
        XCTAssert(isFolder.boolValue,
                  "Folder '\(name)' should be a folder", file: (file), line: line)
        for fileOrFolder in content as! [AssertableFile] {
            fileOrFolder.assertExist(at: location.appendingPathComponent(fileOrFolder.name), fileManager: fileManager, file: (file), line: line)
        }
    }
}

extension InfoPlist: AssertableFile {
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString, line: UInt) {
        XCTAssert(fileManager.fileExists(atPath: location.path),
                  "File '\(name)' should exist at '\(location.path)'", file: (file), line: line)
        
        // TODO: Replace this with PropertListDecoder (see below) when it's available in swift-corelibs-foundation
        // https://github.com/apple/swift-corelibs-foundation/commit/d2d72f88d93f7645b94c21af88a7c9f69c979e4f
        do {
            guard let infoPlistData = fileManager.contents(atPath: location.path) else {
                XCTFail("File '\(name)' does not exist at path \(location.path.singleQuoted)", file: (file), line: line)
                return
            }
            let infoPlist = try PropertyListSerialization.propertyList(from: infoPlistData, options: [], format: nil) as? [String: String]
            
            let displayName = infoPlist?["CFBundleIdentifier"]
            let identifier = infoPlist?["CFBundleVersion"]
            let versionString = infoPlist?["CFBundleDevelopmentRegion"]
            
            XCTAssert(displayName == content.displayName && identifier == content.identifier && versionString == content.versionString,
                      "File '\(name)' should contain the correct information.", file: (file), line: line)
            
        } catch {
            XCTFail("File '\(name)' should contain the correct information.", file: (file), line: line)
        }
    }
}

extension TextFile: AssertableFile {
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString, line: UInt) {
        XCTAssert(fileManager.fileExists(atPath: location.path),
                  "File '\(name)' should exist at '\(location.path)'", file: (file), line: line)
        XCTAssertEqual(fileManager.contents(atPath: location.path).map({ String(data: $0, encoding: .utf8)}), utf8Content,
                       "File '\(name)' should contain '\(utf8Content)'", file: (file), line: line)
    }
}

extension JSONFile: AssertableFile {
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString, line: UInt) {
        XCTAssert(fileManager.fileExists(atPath: location.path),
                  "File '\(name)' should exist at '\(location.path)'", file: (file), line: line)
        
        guard let fileData = fileManager.contents(atPath: location.path),
            let other = try? JSONDecoder().decode(Content.self, from: fileData) else {
            XCTFail("File '\(name)' should contain '\(Content.self)' data at '\(location.path)'", file: (file), line: line)
            return
        }
        
        let encoder = JSONEncoder()
        guard let data = try? encoder.encode(content), let json = try? JSONSerialization.jsonObject(with: data),
            let otherData = try? encoder.encode(other), let otherJSON = try? JSONSerialization.jsonObject(with: otherData)
        else {
            XCTFail("The decoded data in '\(name)' should be encodable as '\(Content.self)'", file: (file), line: line)
            return
        }
        
        switch (json, otherJSON) {
        case let (array as NSArray, otherArray as NSArray):
            XCTAssertEqual(array, otherArray,
                           "File '\(name)' should contain JSON data that is equal to:\n\(array)", file: (file), line: line)
        case let (dictionary as NSDictionary, otherDictionary as NSDictionary):
            XCTAssertEqual(dictionary, otherDictionary,
                           "File '\(name)' should contain JSON data that is equal to:\n\(dictionary)", file: (file), line: line)
        default:
            XCTFail("The decoded data in '\(name)' should be encodable as '\(Content.self)'", file: (file), line: line)
        }
    }
}

extension CopyOfFile: AssertableFile {
    func __assertExist(at location: URL, fileManager: FileManagerProtocol, file: StaticString, line: UInt) {
        XCTAssert(fileManager.fileExists(atPath: location.path),
                  "File '\(name)' should exist at '\(location.path)'", file: (file), line: line)
        
        XCTAssert(fileManager.contentsEqual(atPath: original.path, andPath: location.path),
                  "File '\(name)' should contain the same content as '\(original.path)'", file: (file), line: line)
    }
}