-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Decouple settings vm from user defaults
- Loading branch information
Showing
6 changed files
with
116 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Foundation | ||
import AVFoundation | ||
|
||
protocol AppSettings { | ||
var selectedVoiceIdentifier: String { get set } | ||
var speechRate: Float { get set } | ||
} | ||
|
||
class UserDefaultsSettings: AppSettings { | ||
private let userSettings: UserSettings | ||
|
||
var selectedVoiceIdentifier: String { | ||
didSet { | ||
userSettings.set(selectedVoiceIdentifier, forKey: "selectedVoiceIdentifier") | ||
} | ||
} | ||
var speechRate: Float { | ||
didSet { | ||
userSettings.set(speechRate, forKey: "speechRate") | ||
} | ||
} | ||
init(userDefaults: UserSettings = UserDefaults.standard) { | ||
self.userSettings = userDefaults | ||
if let voiceIdentifier = userSettings.string(forKey: "selectedVoiceIdentifier") { | ||
selectedVoiceIdentifier = voiceIdentifier | ||
} else { | ||
selectedVoiceIdentifier = (AVSpeechSynthesisVoice.speechVoices().first { voice in | ||
voice.language == AVSpeechSynthesisVoice.currentLanguageCode() | ||
})?.identifier ?? "There are no voices installed" | ||
} | ||
self.speechRate = userSettings.float(forKey: "speechRate") | ||
if self.speechRate == 0 { | ||
self.speechRate = AVSpeechUtteranceDefaultSpeechRate | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Foundation | ||
@testable import TypeReader | ||
|
||
// MARK: - AppSettingsMock - | ||
|
||
final class AppSettingsMock: AppSettings { | ||
|
||
// MARK: - selectedVoiceIdentifier | ||
|
||
var selectedVoiceIdentifier: String { | ||
get { underlyingSelectedVoiceIdentifier } | ||
set(value) { underlyingSelectedVoiceIdentifier = value } | ||
} | ||
internal var underlyingSelectedVoiceIdentifier: String! | ||
|
||
// MARK: - speechRate | ||
|
||
var speechRate: Float { | ||
get { underlyingSpeechRate } | ||
set(value) { underlyingSpeechRate = value } | ||
} | ||
internal var underlyingSpeechRate: Float! | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
@testable import TypeReader | ||
import XCTest | ||
import Nimble | ||
|
||
final class UserDefaultsAppSettingsTests: XCTestCase { | ||
func test_SettingsViewModel_whenSettings_shouldSetDefaults() throws { | ||
let defaults = UserDefaults() | ||
let sut = UserDefaultsSettings(userDefaults: defaults) | ||
|
||
sut.speechRate = 1.5 | ||
sut.selectedVoiceIdentifier = "com.apple.speech.synthesis.voice.Princess" | ||
|
||
expect(defaults.string(forKey: "selectedVoiceIdentifier")) == "com.apple.speech.synthesis.voice.Princess" | ||
expect(defaults.float(forKey: "speechRate")) == 1.5 | ||
} | ||
|
||
func test_SettingsViewModel_whenNoDefaults_shouldSetRate() throws { | ||
let mockUserSettings = UserSettingsMock() | ||
mockUserSettings.floatForKeyReturnValue = 0 | ||
|
||
let sut = UserDefaultsSettings(userDefaults: mockUserSettings) | ||
|
||
expect(sut.speechRate) == 0.5 | ||
expect(sut.selectedVoiceIdentifier) != nil | ||
} | ||
} |