diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 48e4e62..20ce8b3 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -6,32 +6,117 @@ on: pull_request: branches: [main] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: run-macos: runs-on: macos-latest - steps: - uses: actions/checkout@v4 - - name: Enable development dependencies + - # Setup testing + name: Enable development dependencies run: | sed -i.bak "s/\/\/dev//g" Package.swift - - name: Build - run: swift build - - name: Run tests - run: swift test --enable-code-coverage - - name: Generate Code Coverage + + - # Run Tests macOS + name: Run Tests macOS run: | + set -o pipefail && \ + env NSUnbufferedIO=YES \ + xcodebuild -workspace . \ + -scheme "Rainbow" \ + -destination "platform=macOS" \ + -enableCodeCoverage YES \ + -derivedDataPath /tmp/DerivedData \ + -resultBundlePath test_output \ + CODE_SIGNING_ALLOWED="NO" \ + test 2>&1 | tee test-macOS.log | xcbeautify + + - name: Upload test log file on error + uses: actions/upload-artifact@v4 + if: failure() + with: + name: test-macOS.log + path: test-macOS.log + + - # Generate Coverage Data + name: Generate code coverage reports + run: | + PROFDATA_PATH=$(find /tmp/DerivedData -name "*.profdata") + echo "Detected profdata at path: $PROFDATA_PATH" + xcrun llvm-cov export \ + /tmp/DerivedData/Build/Products/Debug/RainbowTests.xctest/Contents/MacOS/RainbowTests \ + --instr-profile $PROFDATA_PATH \ + --format="lcov" > RainbowTests.coverage.lcov xcrun llvm-cov export \ - .build/debug/RainbowPackageTests.xctest/Contents/MacOS/RainbowPackageTests \ - -instr-profile .build/debug/codecov/default.profdata \ - --format="lcov" \ - --ignore-filename-regex "\\.build" \ - --ignore-filename-regex "Tests" > info.lcov - - name: Upload Code Coverage + /tmp/DerivedData/Build/Products/Debug/RainbowSwiftUITests.xctest/Contents/MacOS/RainbowSwiftUITests \ + --instr-profile $PROFDATA_PATH \ + --format="lcov" > RainbowSwiftUITests.coverage.lcov + + - # Codecov Coverage + name: Upload coverage to Codecov + uses: codecov/codecov-action@v3.1.1 + with: + fail_ci_if_error: true + files: ./RainbowTests.coverage.lcov,./RainbowSwiftUITests.coverage.lcov + flags: macOS + xcode_archive_path: test_output.xcresults + + run-ios: + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - # Setup testing + name: Enable development dependencies run: | - bash <(curl -s https://codecov.io/bash) \ - -J 'Rainbow' \ - -G info.lcov + sed -i.bak "s/\/\/dev//g" Package.swift + + - # Install dependencies + run: brew install xcbeautify + + # - # Run Tests iOS + # name: Run Tests iOS + # run: | + # set -o pipefail && \ + # env NSUnbufferedIO=YES \ + # xcodebuild -workspace . \ + # -scheme "Rainbow" \ + # -sdk iphonesimulator \ + # -destination "platform=iOS,OS=17.2,name=iPhone 15 Pro" \ + # CODE_SIGNING_ALLOWED="NO" \ + # build test 2>&1 | tee test-iOS.log | xcbeautify + + # - name: Upload test log file on error + # uses: actions/upload-artifact@v4 + # if: failure() + # with: + # name: test-iOS.log + # path: test-iOS.log + + # - # Generate Coverage Data + # name: Generate code coverage reports + # run: | + # PROFDATA_PATH=$(find /tmp/DerivedData -name "*.profdata") + # echo "Detected profdata at path: $PROFDATA_PATH" + # xcrun llvm-cov export \ + # /tmp/DerivedData/Build/Products/Debug-iphonesimulator/RainbowTests.xctest/RainbowTests \ + # --instr-profile $PROFDATA_PATH \ + # --format="lcov" > RainbowTests.coverage.lcov + # xcrun llvm-cov export \ + # /tmp/DerivedData/Build/Products/Debug-iphonesimulator/RainbowSwiftUITests.xctest/RainbowSwiftUITests \ + # --instr-profile $PROFDATA_PATH \ + # --format="lcov" > RainbowSwiftUITests.coverage.lcov + + # - # Codecov Coverage + # name: Upload coverage to Codecov + # uses: codecov/codecov-action@v3.1.1 + # with: + # fail_ci_if_error: true + # files: ./RainbowTests.coverage.lcov,./RainbowSwiftUITests.coverage.lcov + # flags: iOS + # xcode_archive_path: test_output.xcresults swiftlint: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index ad2297b..560920a 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,9 @@ iOSInjectionProject/ # Ruby & Bundler vendor .bundle + +# Test Coverage +*.lcov +test_output +*.log +*.xcresult diff --git a/Package.swift b/Package.swift index 3d73f29..53696e5 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( ], targets: [ .target(name: "Rainbow"), - .target(name: "RainbowSwiftUI"), + .target(name: "RainbowSwiftUI", dependencies: ["Rainbow"]), .testTarget(name: "RainbowTests", dependencies: ["Rainbow"], resources: [ .process("Resources"), ]), diff --git a/Sources/RainbowSwiftUI/Color+Luminance.swift b/Sources/RainbowSwiftUI/Color+Luminance.swift index c40d8d9..d228f1d 100644 --- a/Sources/RainbowSwiftUI/Color+Luminance.swift +++ b/Sources/RainbowSwiftUI/Color+Luminance.swift @@ -1,9 +1,5 @@ +import Rainbow import SwiftUI -#if canImport(AppKit) -import AppKit -#elseif canImport(UIKit) -import UIKit -#endif @available(macOS 10.15, *) public extension Color { @@ -14,19 +10,6 @@ public extension Color { /// - Returns: Luminance ("brightness") of color @available(macOS 11.0, iOS 14.0, *) func luminance() -> CGFloat { - // SwiftUI is handling named colors differently, and the property `cgColor` is not always set. - // Therefore, the SwiftUI.Color is converted to AppKit.UIColor or UIKit.UIColor - #if canImport(AppKit) - let components = NSColor(self).cgColor.components ?? [] - #elseif canImport(UIKit) - let components = UIColor(self).cgColor.components ?? [] - #endif - guard !components.isEmpty else { - return 0 - } - guard components.count >= 3 else { - return components[0] - } - return 0.299 * components[0] + 0.587 * components[1] + 0.114 * components[2] + RainbowColor(self).luminance() } } diff --git a/Tests/RainbowSwiftUITests/Color_LuminanceTests.swift b/Tests/RainbowSwiftUITests/Color_LuminanceTests.swift index a686e5a..176bf49 100644 --- a/Tests/RainbowSwiftUITests/Color_LuminanceTests.swift +++ b/Tests/RainbowSwiftUITests/Color_LuminanceTests.swift @@ -8,22 +8,22 @@ class Color_LuminanceTests: XCTestCase { func testLuminance_dynamicColor_shouldReturnLuminance() { // Act - let luminance = Color("luminance-test-color", bundle: Bundle.module) + let color = Color("luminance-test-color", bundle: Bundle.module) // Assert - XCTAssertEqual(luminance.luminance(), 0.704, accuracy: 0.01) + XCTAssertEqual(color.luminance(), 0.704, accuracy: 0.01) } func testLuminance_grayscaleColor_shouldReturnLuminance() { // Act - let luminance = Color(cgColor: CGColor(gray: 0.3, alpha: 1.0)) + let color = Color(cgColor: CGColor(gray: 0.3, alpha: 1.0)) // Assert - XCTAssertEqual(luminance.luminance(), 0.3, accuracy: 0.01) + XCTAssertEqual(color.luminance(), 0.3, accuracy: 0.01) } func testLuminance_rgbColor_shouldReturnLuminance() { // Act - let luminance = Color(.sRGB, red: 0.5, green: 0.8, blue: 0.2) + let color = Color(.sRGB, red: 0.5, green: 0.8, blue: 0.2) // Assert - XCTAssertEqual(luminance.luminance(), 0.6419, accuracy: 0.00001) + XCTAssertEqual(color.luminance(), 0.6419, accuracy: 0.00001) } } diff --git a/Tests/RainbowTests/RainbowColor_LuminanceTests.swift b/Tests/RainbowTests/RainbowColor_LuminanceTests.swift index 52d4a50..03a19b9 100644 --- a/Tests/RainbowTests/RainbowColor_LuminanceTests.swift +++ b/Tests/RainbowTests/RainbowColor_LuminanceTests.swift @@ -5,15 +5,15 @@ import XCTest class RainbowColor_LuminanceTests: XCTestCase { func testLuminance_grayscaleColor_shouldReturnLuminance() { // Act - let luminance = RainbowColor(cgColor: CGColor(gray: 0.3, alpha: 1.0))! + let color = RainbowColor(white: 0.3, alpha: 1.0) // Assert - XCTAssertEqual(luminance.luminance(), 0.3, accuracy: 0.000001) + XCTAssertEqual(color.luminance(), 0.3) } func testLuminance_rgbColor_shouldReturnLuminance() { // Act - let luminance = RainbowColor(red: 0.5, green: 0.8, blue: 0.2, alpha: 1.0) + let color = RainbowColor(red: 0.5, green: 0.8, blue: 0.2, alpha: 1.0) // Assert - XCTAssertEqual(luminance.luminance(), 0.6419, accuracy: 0.000001) + XCTAssertEqual(color.luminance(), 0.6419, accuracy: 0.000001) } }