import XCTest import CoreGraphics @testable import LChatCore // 🤖 Pins the CGImage adaptation of the reference BlurHash (woltapp/blurhash's // Swift files are UIImage-only and copy-in by design — no package): structure, // round-trip colour fidelity, and malformed-hash rejection. A DCT port's bugs // are subtle; these tests are the confidence the adaptation didn't drift. final class BlurhashTests: XCTestCase { private func solid(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat, w: Int = 32, h: Int = 24) -> CGImage { let cs = CGColorSpaceCreateDeviceRGB() let ctx = CGContext(data: nil, width: w, height: h, bitsPerComponent: 8, bytesPerRow: w * 4, space: cs, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)! // Components in the context's OWN space — the CGColor(red:green:blue:) // convenience creates a generic-space colour that CG converts on draw // (0.3 arrived as 0.405), which read as a codec bug. ctx.setFillColor(CGColor(colorSpace: cs, components: [r, g, b, 1])!) ctx.fill(CGRect(x: 0, y: 0, width: w, height: h)) return ctx.makeImage()! } private func averageRGB(_ image: CGImage) -> (Double, Double, Double) { let w = image.width, h = image.height var data = [UInt8](repeating: 0, count: w * h * 4) let cs = CGColorSpaceCreateDeviceRGB() let ctx = CGContext(data: &data, width: w, height: h, bitsPerComponent: 8, bytesPerRow: w * 4, space: cs, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)! ctx.draw(image, in: CGRect(x: 0, y: 0, width: w, height: h)) var r = 0.0, g = 0.0, b = 0.0 for i in stride(from: 0, to: data.count, by: 4) { r += Double(data[i]); g += Double(data[i + 1]); b += Double(data[i + 2]) } let n = Double(w * h) return (r / n, g / n, b / n) } func testHashShape() throws { let hash = try XCTUnwrap(Blurhash.encode(solid(0.8, 0.3, 0.2))) // 4×3 components: 1 (size) + 1 (max AC) + 4 (DC) + 2×11 (AC) = 28 chars. XCTAssertEqual(hash.count, 28) } // The shared vector grid: 8×6 RGBA, red ramps left→right, green top→bottom, // blue fixed at 64 — keep IDENTICAL to vectorGrid() in test/blurhash.test.mjs. private func vectorImage() -> CGImage { let w = 8, h = 6 var px = [UInt8](repeating: 0, count: w * h * 4) for y in 0..