|
10 | 10 |
|
11 | 11 | @testable @_spi(Experimental) @_spi(ForToolsIntegrationOnly) import Testing
|
12 | 12 | private import _TestingInternals
|
13 |
| -#if canImport(Foundation) |
14 |
| -import Foundation |
15 |
| -@_spi(Experimental) import _Testing_Foundation |
| 13 | +#if canImport(AppKit) |
| 14 | +import AppKit |
| 15 | +@_spi(Experimental) import _Testing_AppKit |
16 | 16 | #endif
|
17 | 17 | #if canImport(CoreGraphics)
|
18 | 18 | import CoreGraphics
|
19 | 19 | @_spi(Experimental) @_spi(ForSwiftTestingOnly) import _Testing_CoreGraphics
|
20 | 20 | #endif
|
| 21 | +#if canImport(Foundation) |
| 22 | +import Foundation |
| 23 | +@_spi(Experimental) import _Testing_Foundation |
| 24 | +#endif |
21 | 25 | #if canImport(UniformTypeIdentifiers)
|
22 | 26 | import UniformTypeIdentifiers
|
23 | 27 | #endif
|
@@ -555,6 +559,71 @@ extension AttachmentTests {
|
555 | 559 | }
|
556 | 560 | }
|
557 | 561 | #endif
|
| 562 | + |
| 563 | +#if canImport(AppKit) |
| 564 | + static var nsImage: NSImage { |
| 565 | + get throws { |
| 566 | + let cgImage = try cgImage.get() |
| 567 | + let size = CGSize(width: CGFloat(cgImage.width), height: CGFloat(cgImage.height)) |
| 568 | + return NSImage(cgImage: cgImage, size: size) |
| 569 | + } |
| 570 | + } |
| 571 | + |
| 572 | + @available(_uttypesAPI, *) |
| 573 | + @Test func attachNSImage() throws { |
| 574 | + let image = try Self.nsImage |
| 575 | + let attachment = Attachment(image, named: "diamond.jpg") |
| 576 | + #expect(attachment.attachableValue.size == image.size) // NSImage makes a copy |
| 577 | + try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in |
| 578 | + #expect(buffer.count > 32) |
| 579 | + } |
| 580 | + } |
| 581 | + |
| 582 | + @available(_uttypesAPI, *) |
| 583 | + @Test func attachNSImageWithCustomRep() throws { |
| 584 | + let image = NSImage(size: NSSize(width: 32.0, height: 32.0), flipped: false) { rect in |
| 585 | + NSColor.red.setFill() |
| 586 | + rect.fill() |
| 587 | + return true |
| 588 | + } |
| 589 | + let attachment = Attachment(image, named: "diamond.jpg") |
| 590 | + #expect(attachment.attachableValue.size == image.size) // NSImage makes a copy |
| 591 | + try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in |
| 592 | + #expect(buffer.count > 32) |
| 593 | + } |
| 594 | + } |
| 595 | + |
| 596 | + @available(_uttypesAPI, *) |
| 597 | + @Test func attachNSImageWithSubclassedNSImage() throws { |
| 598 | + let image = MyImage(size: NSSize(width: 32.0, height: 32.0)) |
| 599 | + image.addRepresentation(NSCustomImageRep(size: image.size, flipped: false) { rect in |
| 600 | + NSColor.green.setFill() |
| 601 | + rect.fill() |
| 602 | + return true |
| 603 | + }) |
| 604 | + |
| 605 | + let attachment = Attachment(image, named: "diamond.jpg") |
| 606 | + #expect(attachment.attachableValue === image) |
| 607 | + #expect(attachment.attachableValue.size == image.size) // NSImage makes a copy |
| 608 | + try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in |
| 609 | + #expect(buffer.count > 32) |
| 610 | + } |
| 611 | + } |
| 612 | + |
| 613 | + @available(_uttypesAPI, *) |
| 614 | + @Test func attachNSImageWithSubclassedRep() throws { |
| 615 | + let image = NSImage(size: NSSize(width: 32.0, height: 32.0)) |
| 616 | + image.addRepresentation(MyImageRep<Int>()) |
| 617 | + |
| 618 | + let attachment = Attachment(image, named: "diamond.jpg") |
| 619 | + #expect(attachment.attachableValue.size == image.size) // NSImage makes a copy |
| 620 | + let firstRep = try #require(attachment.attachableValue.representations.first) |
| 621 | + #expect(!(firstRep is MyImageRep<Int>)) |
| 622 | + try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in |
| 623 | + #expect(buffer.count > 32) |
| 624 | + } |
| 625 | + } |
| 626 | +#endif |
558 | 627 | #endif
|
559 | 628 | }
|
560 | 629 | }
|
@@ -644,3 +713,42 @@ final class MyCodableAndSecureCodingAttachable: NSObject, Codable, NSSecureCodin
|
644 | 713 | }
|
645 | 714 | }
|
646 | 715 | #endif
|
| 716 | + |
| 717 | +#if canImport(AppKit) |
| 718 | +private final class MyImage: NSImage { |
| 719 | + override init(size: NSSize) { |
| 720 | + super.init(size: size) |
| 721 | + } |
| 722 | + |
| 723 | + required init(pasteboardPropertyList propertyList: Any, ofType type: NSPasteboard.PasteboardType) { |
| 724 | + fatalError("Unimplemented") |
| 725 | + } |
| 726 | + |
| 727 | + required init(coder: NSCoder) { |
| 728 | + fatalError("Unimplemented") |
| 729 | + } |
| 730 | + |
| 731 | + override func copy(with zone: NSZone?) -> Any { |
| 732 | + // Intentionally make a copy as NSImage instead of MyImage to exercise the |
| 733 | + // cast-failed code path in the overlay. |
| 734 | + NSImage() |
| 735 | + } |
| 736 | +} |
| 737 | + |
| 738 | +private final class MyImageRep<T>: NSImageRep { |
| 739 | + override init() { |
| 740 | + super.init() |
| 741 | + size = NSSize(width: 32.0, height: 32.0) |
| 742 | + } |
| 743 | + |
| 744 | + required init?(coder: NSCoder) { |
| 745 | + fatalError("Unimplemented") |
| 746 | + } |
| 747 | + |
| 748 | + override func draw() -> Bool { |
| 749 | + NSColor.blue.setFill() |
| 750 | + NSRect(origin: .zero, size: size).fill() |
| 751 | + return true |
| 752 | + } |
| 753 | +} |
| 754 | +#endif |
0 commit comments