File: MockFileSystem.swift

package info (click to toggle)
swiftlang 6.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 2,791,532 kB
  • sloc: cpp: 9,901,743; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (80 lines) | stat: -rw-r--r-- 3,208 bytes parent folder | download | duplicates (2)
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
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2023-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 the list of Swift project authors
//
//===----------------------------------------------------------------------===//

@preconcurrency package import struct SystemPackage.FilePath

/// In-memory implementation of `AsyncFileSystem` for mocking and testing purposes.
package actor MockFileSystem: AsyncFileSystem {
    /// The default size of chunks in bytes read by this file system.
    package static let defaultChunkSize = 512 * 1024

    /// Maximum size of chunks in bytes read by this instance of file system.
    let readChunkSize: Int

    /// Underlying in-memory dictionary-based storage for this mock file system.
    final class Storage {
        init(_ content: [FilePath: [UInt8]]) {
            self.content = content
        }

        var content: [FilePath: [UInt8]]
    }

    /// Concrete instance of the underlying storage used by this file system.
    private let storage: Storage

    /// Creates a new instance of the mock file system.
    /// - Parameters:
    ///   - content: Dictionary of paths to their in-memory contents to use for seeding the file system.
    ///   - readChunkSize: Size of chunks in bytes produced by this file system when reading files.
    package init(content: [FilePath: [UInt8]] = [:], readChunkSize: Int = defaultChunkSize) {
        self.storage = .init(content)
        self.readChunkSize = readChunkSize
    }

    package func exists(_ path: FilePath) -> Bool {
        self.storage.content.keys.contains(path)
    }

    /// Writes a sequence of bytes to a file. Any existing content is replaced with new content.
    /// - Parameters:
    ///   - path: absolute path of the file to write bytes to.
    ///   - bytes: sequence of bytes to write to file's contents replacing old content.
    func write(path: FilePath, bytes: some Sequence<UInt8>) {
        storage.content[path] = Array(bytes)
    }

    /// Appends a sequence of bytes to a file.
    /// - Parameters:
    ///   - path: absolute path of the file to append bytes to.
    ///   - bytes: sequence of bytes to append to file's contents.
    func append(path: FilePath, bytes: some Sequence<UInt8>) {
        storage.content[path, default: []].append(contentsOf: bytes)
    }

    package func withOpenReadableFile<T: Sendable>(
        _ path: FilePath,
        _ body: (OpenReadableFile) async throws -> T
    ) async throws -> T {
        guard let bytes = storage.content[path] else {
            throw AsyncFileSystemError.fileDoesNotExist(path)
        }
        return try await body(.init(chunkSize: self.readChunkSize, fileHandle: .mock(bytes)))
    }

    package func withOpenWritableFile<T: Sendable>(
        _ path: FilePath,
        _ body: (OpenWritableFile) async throws -> T
    ) async throws -> T {
        try await body(.init(storage: .mock(self), path: path))
    }
}