Skip to content

Commit

Permalink
Add unit test for accessibility shortcuts
Browse files Browse the repository at this point in the history
  • Loading branch information
1024jp committed Dec 2, 2024
1 parent 2394d6d commit ca5e2a5
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CotEditor/Sources/Setting Managers/KeyBindingManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ import URLUtils

static let shared = KeyBindingManager()

let defaultKeyBindings: [KeyBinding]


// MARK: Private Properties

private let defaultKeyBindings: [KeyBinding]
private var userKeyBindings: [KeyBinding] = []
private var modifiedKeyBindings: Set<KeyBinding> = []

Expand Down
4 changes: 3 additions & 1 deletion Packages/MacUI/Sources/Shortcut/Shortcut.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ public struct Shortcut: Sendable {

/// Initializes Shortcut directly from a key equivalent character and modifiers.
///
/// - Note: This initializer accepts the fn key while the others not.
/// - Note: This initializer accepts the Fn key while the others not.
public init?(_ keyEquivalent: String, modifiers: NSEvent.ModifierFlags) {

assert(keyEquivalent.count <= 1)

guard !keyEquivalent.isEmpty else { return nil }

self.keyEquivalent = keyEquivalent
Expand Down
93 changes: 93 additions & 0 deletions Tests/Sources/Models/KeyBindingTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// KeyBindingTests.swift
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2024-12-02.
//
// ---------------------------------------------------------------------------
//
// © 2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Testing
import Shortcut
import AppKit.NSEvent
@testable import CotEditor


struct KeyBindingTests {

/// Shortcuts that are reserved for use with the Accessibility features in macOS.
///
/// - SeeAlso: [Accessibility shortcuts](https://support.apple.com/en-us/102650#accessibility)
private let accessibilityShortcuts: Set<Shortcut> = [
// vision shortcuts
Shortcut("8", modifiers: [.control, .option, .command])!,
Shortcut(",", modifiers: [.control, .option, .command])!,
Shortcut(".", modifiers: [.control, .option, .command])!,

// moving keyboard focus
Shortcut(.f2, modifiers: [.control]),
Shortcut(.f3, modifiers: [.control]),
Shortcut(.f4, modifiers: [.control]),
Shortcut(.f5, modifiers: [.control]),
Shortcut(.f6, modifiers: [.control]),
Shortcut(.f6, modifiers: [.control, .shift]),
Shortcut(.f7, modifiers: [.control]),
Shortcut(.f8, modifiers: [.control]),
Shortcut("`", modifiers: [.command])!,
Shortcut("`", modifiers: [.shift, .command])!,
Shortcut("`", modifiers: [.option, .command])!,
Shortcut(.tab, modifiers: [.shift]),
Shortcut(.tab, modifiers: [.control]),
Shortcut(.tab, modifiers: [.control, .shift]),
Shortcut(.upArrow, modifiers: [.control]),
Shortcut(.downArrow, modifiers: [.control]),
Shortcut(.leftArrow, modifiers: [.control]),
Shortcut(.rightArrow, modifiers: [.control]),

/// showing accessibility shortcut panel
Shortcut(.f5, modifiers: [.option, .command]),

/// toggling VoiceOver
Shortcut(.f5, modifiers: [.command]),
]


/// Tests .defaultKeyBindings expectedly contains key bindings determined in CotEditor.
@Test func defaultKeyBindings() async {

let keyBindings = await KeyBindingManager.shared.defaultKeyBindings

#expect(keyBindings
.compactMap(\.shortcut)
.contains(Shortcut("k", modifiers: .command)!))
}


@Test func reservedShortcuts() async {

let keyBindings = await KeyBindingManager.shared.defaultKeyBindings

for keyBinding in keyBindings {
guard let shortcut = keyBinding.shortcut else { continue }

#expect(!self.accessibilityShortcuts.contains(shortcut),
"\(keyBinding.action) overrides the accessibility shortcut “\(shortcut.symbol)")
}
}
}

0 comments on commit ca5e2a5

Please sign in to comment.