Skip to content

Commit

Permalink
refactor: wrapping for semantic tokens of borders (#79) (WIP)
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre-Yves Lapersonne <[email protected]>
  • Loading branch information
pylapp committed Dec 13, 2024
1 parent 0145ba7 commit bbec5ab
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Foundation
import OUDSTokensRaw
import OUDSTokensSemantic

extension OUDSTheme: BorderSemanticTokens {
extension OUDSBorderSemanticTokensWrapper: BorderSemanticTokens {
@objc open var borderRadiusDefault: BorderRadiusSemanticToken { BorderRawTokens.borderRadius0 }
@objc open var borderRadiusMedium: BorderRadiusSemanticToken { BorderRawTokens.borderRadius150 }
@objc open var borderRadiusNone: BorderRadiusSemanticToken { BorderRawTokens.borderRadius0 }
Expand Down
23 changes: 17 additions & 6 deletions OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,41 @@ import OUDSTokensSemantic
/// Any properties of an overridable theme should be defined so as to provide defaults values.
/// We allow this theme to be derivated and be overriden.
///
/// `OUDSTheme` can be seen as a kind of "abstract class" in _object oriented paradigm_.
/// ``OUDSTheme`` can be seen as a kind of "abstract class" in _object oriented paradigm_.
///
/// Because `OUDSTheme` is not a *final* class, its type cannot be seen as `Sendable`, that is the reason why this conformity is unchecked.
///
/// **Warning: You are not supposed to use this abstract default theme directly. Please prefer `OrangeTheme` instead**
open class OUDSTheme: @unchecked Sendable {

// MARK: - Properties

/// All semantic tokens of border exposed in one object
public let borders: BorderSemanticTokens

/// A theme can have a custom font which is not the system font
public let customFontFamily: FontFamilySemanticToken?

// MARK: - Initializers

/// Defines a basic kind of abstract theme to subclass then.
/// No custom font family will be used.
public convenience init() {
self.init(customFontFamily: nil)
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, by default `OUDSBorderSemanticTokensWrapper`
public init(borders: BorderSemanticTokens = OUDSBorderSemanticTokensWrapper()) {
self.borders = borders
customFontFamily = nil
}

/// Defines a basic kind of abstract theme to subclass then.
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, as `BorderSemanticTokens` implementation
/// - customFontFamily: Set `nil` if system font to use, otherwise use the `FontFamilySemanticToken` you want to apply
public init(customFontFamily: FontFamilySemanticToken?) {
public init(borders: BorderSemanticTokens,
customFontFamily: FontFamilySemanticToken?) {
self.customFontFamily = customFontFamily
self.borders = borders
}

deinit { }

// Please refer to extensions for properties, it will be more clear
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT
//
// This software is distributed under the MIT license,
// the text of which is available at https://opensource.org/license/MIT/
// the text of which is available at https://publicsource.org/license/MIT/
// or see the "LICENSE" file for more details.
//
// Authors: See CONTRIBUTORS.txt
Expand All @@ -15,35 +15,39 @@ import Foundation
import OUDSTokensRaw
import OUDSTokensSemantic

/// Overrides **all** the border semantic tokens (from its super class, i.e. `OUDSTheme` so as to test overriding of them (unit tests)
// swiftlint:disable required_deinit

/// Overrides **all** the border semantic tokens (from its super class, i.e. `OUDSBorderSemanticTokensWrapper` so as to test overriding of them (unit tests)
/// and to act like smoke tests with crashing tests if some tokens disappeared.
extension MockTheme {
final class MockThemeBorderSemanticTokensWrapper: OUDSBorderSemanticTokensWrapper {

static let mockThemeBorderWidthRawToken: BorderWidthRawToken = 1_337
static let mockThemeBorderRadiusRawToken: BorderRadiusRawToken = 42
static let mockThemeBorderStyleRawToken: BorderStyleRawToken = "(╯°□°)╯︵ ┻━┻"

// MARK: Semantic token - Border - Width

override open var borderWidthNone: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthDefault: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthThin: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthMedium: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthThick: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthThicker: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthFocus: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override open var borderWidthFocusInset: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthNone: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthDefault: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthThin: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthMedium: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthThick: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthThicker: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthFocus: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }
override public var borderWidthFocusInset: BorderWidthSemanticToken { Self.mockThemeBorderWidthRawToken }

// MARK: Semantic token - Border - Radius

override open var borderRadiusNone: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override open var borderRadiusDefault: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override open var borderRadiusShort: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override open var borderRadiusMedium: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override open var borderRadiusTall: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override public var borderRadiusNone: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override public var borderRadiusDefault: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override public var borderRadiusShort: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override public var borderRadiusMedium: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }
override public var borderRadiusTall: BorderRadiusSemanticToken { Self.mockThemeBorderRadiusRawToken }

// MARK: Semantic token - Border - Style

override open var borderStyleDefault: BorderStyleSemanticToken { Self.mockThemeBorderStyleRawToken }
override open var borderStyleDrag: BorderStyleSemanticToken { Self.mockThemeBorderStyleRawToken }
override public var borderStyleDefault: BorderStyleSemanticToken { Self.mockThemeBorderStyleRawToken }
override public var borderStyleDrag: BorderStyleSemanticToken { Self.mockThemeBorderStyleRawToken }
}

// swiftlint:enable required_deinit
11 changes: 7 additions & 4 deletions OUDS/Core/OUDS/Tests/OUDSTheme/MockThemes/MockTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ import Foundation
import OUDS
import OUDSTokensSemantic

/// A mock theme for tests
/// A mock theme for tests. It helps to make tests on themes, mainly for the architecture and the overriding of tokens.
/// *open* to allow some derivative mock themes like ``OtherMockTheme``.
///
/// Uses its own tokens wrappers for tests:
/// - ``MockThemeBorderSemanticTokensWrapper`` for borders
open class MockTheme: OUDSTheme, @unchecked Sendable {

convenience init() {
self.init(customFont: nil)
}

init(customFont: String?) {
super.init(customFontFamily: customFont)
super.init(borders: MockThemeBorderSemanticTokensWrapper(),
customFontFamily: customFont)
}

deinit { }

// Please refer to extensions
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,82 +36,82 @@ final class TestThemeOverrideOfBorderSemanticTokens: XCTestCase {
// MARK: - Semantic token - Border - Width

func testInheritedThemeCanOverrideSemanticTokenBorderWidthNone() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthNone, abstractTheme.borderWidthNone)
XCTAssertTrue(inheritedTheme.borderWidthNone == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthNone, abstractTheme.borders.borderWidthNone)
XCTAssertTrue(inheritedTheme.borders.borderWidthNone == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthDefault() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthDefault, abstractTheme.borderWidthDefault)
XCTAssertTrue(inheritedTheme.borderWidthDefault == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthDefault, abstractTheme.borders.borderWidthDefault)
XCTAssertTrue(inheritedTheme.borders.borderWidthDefault == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthThin() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthThin, abstractTheme.borderWidthThin)
XCTAssertTrue(inheritedTheme.borderWidthThin == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthThin, abstractTheme.borders.borderWidthThin)
XCTAssertTrue(inheritedTheme.borders.borderWidthThin == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthMedium() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthMedium, abstractTheme.borderWidthMedium)
XCTAssertTrue(inheritedTheme.borderWidthMedium == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthMedium, abstractTheme.borders.borderWidthMedium)
XCTAssertTrue(inheritedTheme.borders.borderWidthMedium == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthThick() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthThick, abstractTheme.borderWidthThick)
XCTAssertTrue(inheritedTheme.borderWidthThick == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthThick, abstractTheme.borders.borderWidthThick)
XCTAssertTrue(inheritedTheme.borders.borderWidthThick == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthThicker() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthThicker, abstractTheme.borderWidthThicker)
XCTAssertTrue(inheritedTheme.borderWidthThicker == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthThicker, abstractTheme.borders.borderWidthThicker)
XCTAssertTrue(inheritedTheme.borders.borderWidthThicker == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthFocus() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthFocus, abstractTheme.borderWidthFocus)
XCTAssertTrue(inheritedTheme.borderWidthFocus == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthFocus, abstractTheme.borders.borderWidthFocus)
XCTAssertTrue(inheritedTheme.borders.borderWidthFocus == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderWidthFocusInset() throws {
XCTAssertNotEqual(inheritedTheme.borderWidthFocusInset, abstractTheme.borderWidthFocusInset)
XCTAssertTrue(inheritedTheme.borderWidthFocusInset == MockTheme.mockThemeBorderWidthRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderWidthFocusInset, abstractTheme.borders.borderWidthFocusInset)
XCTAssertTrue(inheritedTheme.borders.borderWidthFocusInset == MockThemeBorderSemanticTokensWrapper.mockThemeBorderWidthRawToken)
}

// MARK: - Semantic token - Border - Radius

func testInheritedThemeCanOverrideSemanticTokenBorderRadiusNone() throws {
XCTAssertNotEqual(inheritedTheme.borderRadiusNone, abstractTheme.borderRadiusNone)
XCTAssertTrue(inheritedTheme.borderRadiusNone == MockTheme.mockThemeBorderRadiusRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderRadiusNone, abstractTheme.borders.borderRadiusNone)
XCTAssertTrue(inheritedTheme.borders.borderRadiusNone == MockThemeBorderSemanticTokensWrapper.mockThemeBorderRadiusRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderRadiusDefault() throws {
XCTAssertNotEqual(inheritedTheme.borderRadiusDefault, abstractTheme.borderRadiusDefault)
XCTAssertTrue(inheritedTheme.borderRadiusDefault == MockTheme.mockThemeBorderRadiusRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderRadiusDefault, abstractTheme.borders.borderRadiusDefault)
XCTAssertTrue(inheritedTheme.borders.borderRadiusDefault == MockThemeBorderSemanticTokensWrapper.mockThemeBorderRadiusRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderRadiusShort() throws {
XCTAssertNotEqual(inheritedTheme.borderRadiusShort, abstractTheme.borderRadiusShort)
XCTAssertTrue(inheritedTheme.borderRadiusShort == MockTheme.mockThemeBorderRadiusRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderRadiusShort, abstractTheme.borders.borderRadiusShort)
XCTAssertTrue(inheritedTheme.borders.borderRadiusShort == MockThemeBorderSemanticTokensWrapper.mockThemeBorderRadiusRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderRadiusMedium() throws {
XCTAssertNotEqual(inheritedTheme.borderRadiusMedium, abstractTheme.borderRadiusMedium)
XCTAssertTrue(inheritedTheme.borderRadiusMedium == MockTheme.mockThemeBorderRadiusRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderRadiusMedium, abstractTheme.borders.borderRadiusMedium)
XCTAssertTrue(inheritedTheme.borders.borderRadiusMedium == MockThemeBorderSemanticTokensWrapper.mockThemeBorderRadiusRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderRadiusTall() throws {
XCTAssertNotEqual(inheritedTheme.borderRadiusTall, abstractTheme.borderRadiusTall)
XCTAssertTrue(inheritedTheme.borderRadiusTall == MockTheme.mockThemeBorderRadiusRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderRadiusTall, abstractTheme.borders.borderRadiusTall)
XCTAssertTrue(inheritedTheme.borders.borderRadiusTall == MockThemeBorderSemanticTokensWrapper.mockThemeBorderRadiusRawToken)
}

// MARK: - Semantic token - Border - Style

func testInheritedThemeCanOverrideSemanticTokenBorderStyleDefault() throws {
XCTAssertNotEqual(inheritedTheme.borderStyleDefault, abstractTheme.borderStyleDefault)
XCTAssertTrue(inheritedTheme.borderStyleDefault == MockTheme.mockThemeBorderStyleRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderStyleDefault, abstractTheme.borders.borderStyleDefault)
XCTAssertTrue(inheritedTheme.borders.borderStyleDefault == MockThemeBorderSemanticTokensWrapper.mockThemeBorderStyleRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenBorderStyleDrag() throws {
XCTAssertNotEqual(inheritedTheme.borderStyleDrag, abstractTheme.borderStyleDrag)
XCTAssertTrue(inheritedTheme.borderStyleDrag == MockTheme.mockThemeBorderStyleRawToken)
XCTAssertNotEqual(inheritedTheme.borders.borderStyleDrag, abstractTheme.borders.borderStyleDrag)
XCTAssertTrue(inheritedTheme.borders.borderStyleDrag == MockThemeBorderSemanticTokensWrapper.mockThemeBorderStyleRawToken)
}
}

Expand Down
17 changes: 13 additions & 4 deletions OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@
//

import OUDS
import OUDSTokensSemantic

/// This is an override of the default basic ``OUDSTheme` and should be seen as the default theme for the OUDS library.
/// It can overrides any properties from its superclass, and can be derived too.
/// This is an override of the default basic ``OUDSTheme`` and should be seen as the default theme for the OUDS library.
/// It can override any properties from its superclass, and can be derived too.
open class OrangeTheme: OUDSTheme, @unchecked Sendable {

deinit { }
// MARK: - Initializers

// For clarity reasons, please override OUDSTheme properties in extensions
/// Defines a basic kind of abstract theme to subclass then.
/// No custom font family will be used.
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, as `BorderSemanticTokens` implementation
public override init(borders: BorderSemanticTokens) {

Check failure on line 27 in OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Modifier Order (modifier_order)

override modifier should come before public
super.init(borders: borders)
}

Check failure on line 30 in OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Trailing Whitespace (trailing_whitespace)

Lines should not have trailing whitespace
deinit { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

/// This is a group of semantic tokens for **borders**.
/// It defines all ``BorderWidthSemanticToken``, ``BorderRadiusSemanticToken`` and ``BorderStyleSemanticToken`` a theme must have.
/// Any border semantic token must be declared there.
/// Any border semantic token must be declared there as wrappers like ``OUDSBorderSemanticTokensWrapper`` will then expose them through `OUDSTheme`.
public protocol BorderSemanticTokens {

// MARK: - Semantic token - Border - Width
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Software Name: OUDS iOS
// SPDX-FileCopyrightText: Copyright (c) Orange SA
// SPDX-License-Identifier: MIT
//
// This software is distributed under the MIT license,
// the text of which is available at https://opensource.org/license/MIT/
// or see the "LICENSE" file for more details.
//
// Authors: See CONTRIBUTORS.txt
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
//

/// A class which wraps all ``BorderSemanticTokens`` and expose them.
/// This wrapper should be integrated as a ``BorderSemanticTokens`` implementation inside `OUDSTheme` so as to provide
/// all tokens to the users.
open class OUDSBorderSemanticTokensWrapper {

/// Intializes the wrapper
public init() { }

deinit{ }

// ଘ( ・ω・)_/゚・:*:・。☆
// Note: So as to help the integration of generated code produced by the tokenator
// the implemention of BorderSemanticTokens is not here but in OUDS/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+BorderSemanticTokens.swift
// This declaration of BorderSemanticTokensWrapper is here to allow to write documentation.
}
Loading

0 comments on commit bbec5ab

Please sign in to comment.