Files
2026-10-15 13:57:57 +02:00

51 lines
2.4 KiB
Swift

import AppKit
import Testing
@testable import Conjure
@Test @MainActor
func iconsScaleWithTypographyWithoutEnlargingSymbolsToApplicationSize() throws {
_ = NSApplication.shared
let artwork = NSImage(size: NSSize(width: 128, height: 128), flipped: false) { rect in
NSColor.white.setFill()
rect.fill()
return true
}
var rendered: [(application: CGFloat, symbol: CGFloat)] = []
for (textSize, expectedApplicationSize): (CGFloat, CGFloat) in [(14, 22), (28, 44)] {
let host = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
let icon = IconView(font: .systemFont(ofSize: textSize, weight: .medium))
host.addSubview(icon)
NSLayoutConstraint.activate([
icon.centerXAnchor.constraint(equalTo: host.centerXAnchor),
icon.centerYAnchor.constraint(equalTo: host.centerYAnchor)
])
host.layoutSubtreeIfNeeded()
#expect(icon.frame.size == NSSize(width: expectedApplicationSize, height: expectedApplicationSize))
func artworkHeight() throws -> CGFloat {
let bitmap = try #require(icon.bitmapImageRepForCachingDisplay(in: icon.bounds))
icon.cacheDisplay(in: icon.bounds, to: bitmap)
var first = bitmap.pixelsHigh
var last = -1
for y in 0..<bitmap.pixelsHigh {
for x in 0..<bitmap.pixelsWide where (bitmap.colorAt(x: x, y: y)?.alphaComponent ?? 0) > 0.5 {
first = min(first, y)
last = max(last, y)
}
}
return CGFloat(last - first + 1) * icon.bounds.height / CGFloat(bitmap.pixelsHigh)
}
icon.image = artwork
let applicationHeight = try artworkHeight()
// Reuse the same slot, as launcher cells do when switching to command/calculator results.
icon.image = NSImage(systemSymbolName: "stop.circle", accessibilityDescription: nil)
let symbolHeight = try artworkHeight()
#expect(applicationHeight == expectedApplicationSize)
#expect(symbolHeight > textSize * 0.75 && symbolHeight <= textSize)
icon.image = artwork
#expect(try artworkHeight() == applicationHeight)
rendered.append((applicationHeight, symbolHeight))
}
#expect(rendered[1].application == rendered[0].application * 2)
#expect(abs(rendered[1].symbol - rendered[0].symbol * 2) <= 1)
}