|
7 | 7 | // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
8 | 8 | //
|
9 | 9 |
|
| 10 | +import CoreFoundation |
| 11 | + |
| 12 | +#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT |
| 13 | + #if canImport(SwiftFoundation) && !DEPLOYMENT_RUNTIME_OBJC |
| 14 | + @testable import SwiftFoundation |
| 15 | + #else |
| 16 | + @testable import Foundation |
| 17 | + #endif |
| 18 | +#endif |
| 19 | + |
10 | 20 | class TestNSData: LoopbackServerTest {
|
11 | 21 |
|
12 | 22 | class AllOnesImmutableData : NSData {
|
@@ -223,6 +233,8 @@ class TestNSData: LoopbackServerTest {
|
223 | 233 | ("test_limitDebugDescription", test_limitDebugDescription),
|
224 | 234 | ("test_edgeDebugDescription", test_edgeDebugDescription),
|
225 | 235 | ("test_writeToURLOptions", test_writeToURLOptions),
|
| 236 | + ("test_writeToURLPermissions", test_writeToURLPermissions), |
| 237 | + ("test_writeToURLPermissionsWithAtomic", test_writeToURLPermissionsWithAtomic), |
226 | 238 | ("test_edgeNoCopyDescription", test_edgeNoCopyDescription),
|
227 | 239 | ("test_initializeWithBase64EncodedDataGetsDecodedData", test_initializeWithBase64EncodedDataGetsDecodedData),
|
228 | 240 | ("test_initializeWithBase64EncodedDataWithNonBase64CharacterIsNil", test_initializeWithBase64EncodedDataWithNonBase64CharacterIsNil),
|
@@ -551,6 +563,61 @@ class TestNSData: LoopbackServerTest {
|
551 | 563 | }
|
552 | 564 | }
|
553 | 565 |
|
| 566 | +#if !os(Windows) |
| 567 | + // NOTE: `umask(3)` is process global. Therefore, the behavior is unknown if `withUmask(_:_:)` is used simultaniously. |
| 568 | + private func withUmask(_ mode: mode_t, _ block: () -> Void) { |
| 569 | + let original = umask(mode) |
| 570 | + block() |
| 571 | + umask(original) |
| 572 | + } |
| 573 | +#endif |
| 574 | + |
| 575 | + func test_writeToURLPermissions() { |
| 576 | +#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT && !os(Windows) |
| 577 | + withUmask(0) { |
| 578 | + do { |
| 579 | + let data = Data() |
| 580 | + let url = URL(fileURLWithPath: NSTemporaryDirectory() + "meow") |
| 581 | + try data.write(to: url) |
| 582 | + let fileManager = FileManager.default |
| 583 | + let permission = try fileManager._permissionsOfItem(atPath: url.path) |
| 584 | +#if canImport(Darwin) |
| 585 | + let expected = Int(S_IRUSR) | Int(S_IWUSR) | Int(S_IRGRP) | Int(S_IWGRP) | Int(S_IROTH) | Int(S_IWOTH) |
| 586 | +#else |
| 587 | + let expected = Int(Glibc.S_IRUSR) | Int(Glibc.S_IWUSR) | Int(Glibc.S_IRGRP) | Int(Glibc.S_IWGRP) | Int(Glibc.S_IROTH) | Int(Glibc.S_IWOTH) |
| 588 | +#endif |
| 589 | + XCTAssertEqual(permission, expected) |
| 590 | + try! fileManager.removeItem(atPath: url.path) |
| 591 | + } catch { |
| 592 | + XCTFail() |
| 593 | + } |
| 594 | + } |
| 595 | +#endif |
| 596 | + } |
| 597 | + |
| 598 | + func test_writeToURLPermissionsWithAtomic() { |
| 599 | +#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT && !os(Windows) |
| 600 | + withUmask(0) { |
| 601 | + do { |
| 602 | + let data = Data() |
| 603 | + let url = URL(fileURLWithPath: NSTemporaryDirectory() + "meow") |
| 604 | + try data.write(to: url, options: .atomic) |
| 605 | + let fileManager = FileManager.default |
| 606 | + let permission = try fileManager._permissionsOfItem(atPath: url.path) |
| 607 | +#if canImport(Darwin) |
| 608 | + let expected = Int(S_IRUSR) | Int(S_IWUSR) | Int(S_IRGRP) | Int(S_IWGRP) | Int(S_IROTH) | Int(S_IWOTH) |
| 609 | +#else |
| 610 | + let expected = Int(Glibc.S_IRUSR) | Int(Glibc.S_IWUSR) | Int(Glibc.S_IRGRP) | Int(Glibc.S_IWGRP) | Int(Glibc.S_IROTH) | Int(Glibc.S_IWOTH) |
| 611 | +#endif |
| 612 | + XCTAssertEqual(permission, expected) |
| 613 | + try! fileManager.removeItem(atPath: url.path) |
| 614 | + } catch { |
| 615 | + XCTFail() |
| 616 | + } |
| 617 | + } |
| 618 | +#endif |
| 619 | + } |
| 620 | + |
554 | 621 | func test_emptyDescription() {
|
555 | 622 | let expected = "<>"
|
556 | 623 |
|
|
0 commit comments