Skip to content

Commit

Permalink
New avatar colors + tests (#22)
Browse files Browse the repository at this point in the history
* new avatar colors + tests

* better docs

* the init can actually be public

* Apply suggestions from code review

Co-authored-by: Doug <[email protected]>

* code improvement

* Create tests.yml

* changed the name to Tests

* better naming of the workflow

* running tests using xcodebuild

* not specifying minor version

* tests are OS independent

* using the same runner of el-x

---------

Co-authored-by: Doug <[email protected]>
  • Loading branch information
Velin92 and pixlwave authored Aug 31, 2023
1 parent 50bb7cf commit 5ab4197
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This workflow will build a Swift project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift

name: Tests

on:
pull_request:
branches: [ "main" ]

jobs:
tests:

runs-on: macos-13

steps:
- uses: actions/checkout@v3
- name: Run tests
run: xcodebuild test -scheme 'Compound' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14'

36 changes: 36 additions & 0 deletions Sources/Compound/Colors/CompoundColors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,26 @@ public struct CompoundColors {
public let bgSubtleSecondaryLevel0 = Color(UIColor { $0.isLight ? UIColor(compound.colorGray300) : UIColor(compound.colorThemeBg) })
public let bgCanvasDefaultLevel1 = Color(UIColor { $0.isLight ? UIColor(compound.colorThemeBg) : UIColor(compound.colorGray300) })

// MARK: - Avatar Colors
// Used to determine the background color and the foreground color of an avatar.

// Order matches the one from web
// https://github.com/vector-im/compound-web/blob/5dda11aa9733462fb8422968181275bc3e9b35e3/src/components/Avatar/Avatar.module.css#L64
internal let avatarColors: [AvatarColor] = [
.init(background: compound.colorBlue300, foreground: compound.colorBlue1200),
.init(background: compound.colorFuchsia300, foreground: compound.colorFuchsia1200),
.init(background: compound.colorGreen300, foreground: compound.colorGreen1200),
.init(background: compound.colorPink300, foreground: compound.colorPink1200),
.init(background: compound.colorOrange300, foreground: compound.colorOrange1200),
.init(background: compound.colorCyan300, foreground: compound.colorCyan1200),
.init(background: compound.colorPurple300, foreground: compound.colorPurple1200),
.init(background: compound.colorLime300, foreground: compound.colorLime1200)
]

public func avatarColor(for contentID: String) -> AvatarColor {
avatarColors[contentID.hashCode]
}

// MARK: - Awaiting Semantic Tokens

/// This token is a placeholder and hasn't been finalised.
Expand Down Expand Up @@ -125,3 +145,19 @@ private extension UITraitCollection {
/// Whether or not the trait collection contains a `userInterfaceStyle` of `.light`.
var isLight: Bool { userInterfaceStyle == .light }
}

public struct AvatarColor: Equatable {
let background: Color
let foreground: Color
}

private extension String {
/// Calculates a numeric hash same as Element Web
/// See original function here https://github.com/matrix-org/matrix-react-sdk/blob/321dd49db4fbe360fc2ff109ac117305c955b061/src/utils/FormattingUtils.js#L47
var hashCode: Int {
let characterCodeSum = self.reduce(0) { sum, character in
sum + Int(character.unicodeScalars.first?.value ?? 0)
}
return (characterCodeSum % Color.compound.avatarColors.count)
}
}
46 changes: 46 additions & 0 deletions Tests/CompoundTests/AvatarColorsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// File.swift
//
//
// Created by Mauro Romito on 31/08/23.
//

import Foundation

@testable import Compound
import SwiftUI
import XCTest

final class AvatarColorsTests: XCTestCase {
struct TestCase {
let input: String
private let webOutput: Int

// remember that web starts the index from 1 while we start from 0
var output: Int {
webOutput - 1
}

init(input: String, webOutput: Int) {
self.input = input
self.webOutput = webOutput
}
}

func testAvatarColorHash() {
// Match the tests with the web ones for consistency between the two platforms
// https://github.com/vector-im/compound-web/blob/5dda11aa9733462fb8422968181275bc3e9b35e3/src/components/Avatar/Avatar.test.tsx#L62
let testCases: [TestCase] = [
.init(input: "@bob:example.org", webOutput: 8),
.init(input: "@alice:example.org", webOutput: 3),
.init(input: "@charlie:example.org", webOutput: 5),
.init(input: "@dan:example.org", webOutput: 8),
.init(input: "@elena:example.org", webOutput: 2),
.init(input: "@fanny:example.org", webOutput: 1)
]

for testCase in testCases {
XCTAssertEqual(Color.compound.avatarColor(for: testCase.input), Color.compound.avatarColors[testCase.output])
}
}
}

0 comments on commit 5ab4197

Please sign in to comment.