PR Fixes. Move .initial factory method to test target. Rename given() to apply(chip:group:) and make it a member function

This commit is contained in:
Francisco Gindre 2021-12-20 19:27:30 -03:00
parent a2546abee6
commit e94021b4be
2 changed files with 42 additions and 38 deletions

View File

@ -58,19 +58,6 @@ struct RecoveryPhraseValidationState: Equatable {
extension RecoveryPhraseValidationState {
static func initial(
phrase: RecoveryPhrase,
missingIndices: [Int],
missingWordsChips: [PhraseChip.Kind]
) -> Self {
RecoveryPhraseValidationState(
phrase: phrase,
missingIndices: missingIndices,
missingWordChips: missingWordsChips,
completion: []
)
}
/// creates an initial `RecoveryPhraseValidationState` with no completions and random missing indices.
/// - Note: Use this function to create a random validation puzzle for a given phrase.
static func random(phrase: RecoveryPhrase) -> Self {
@ -119,60 +106,60 @@ extension RecoveryPhraseValidationState {
}
/// drives the state machine represented on this Enum by the action of applying a chip into a group of words containing an empty slot that has to be completed
static func given(_ state: RecoveryPhraseValidationState, apply chip: PhraseChip.Kind, into group: Int) -> Self {
guard case let PhraseChip.Kind.unassigned(word) = chip else { return state }
func apply(chip: PhraseChip.Kind, into group: Int) -> Self {
guard case let PhraseChip.Kind.unassigned(word) = chip else { return self }
switch state.step {
switch self.step {
case .initial:
guard let missingChipIndex = state.missingWordChips.firstIndex(of: chip) else { return state }
guard let missingChipIndex = missingWordChips.firstIndex(of: chip) else { return self }
var newMissingWords = state.missingWordChips
var newMissingWords = missingWordChips
newMissingWords[missingChipIndex] = .empty
return RecoveryPhraseValidationState(
phrase: state.phrase,
missingIndices: state.missingIndices,
phrase: phrase,
missingIndices: missingIndices,
missingWordChips: newMissingWords,
completion: [RecoveryPhraseStepCompletion(groupIndex: group, word: word)]
)
case .incomplete:
guard let missingChipIndex = state.missingWordChips.firstIndex(of: chip) else { return state }
guard let missingChipIndex = missingWordChips.firstIndex(of: chip) else { return self }
if state.completion.count < (RecoveryPhraseValidationState.phraseChunks - 1) {
var newMissingWords = state.missingWordChips
if completion.count < (RecoveryPhraseValidationState.phraseChunks - 1) {
var newMissingWords = missingWordChips
newMissingWords[missingChipIndex] = .empty
var newCompletionState = Array(state.completion)
var newCompletionState = Array(completion)
newCompletionState.append(RecoveryPhraseStepCompletion(groupIndex: group, word: word))
return RecoveryPhraseValidationState(
phrase: state.phrase,
missingIndices: state.missingIndices,
phrase: phrase,
missingIndices: missingIndices,
missingWordChips: newMissingWords,
completion: newCompletionState
)
} else {
var newCompletion = state.completion
var newCompletion = completion
newCompletion.append(RecoveryPhraseStepCompletion(groupIndex: group, word: word))
return RecoveryPhraseValidationState(
phrase: state.phrase,
missingIndices: state.missingIndices,
phrase: phrase,
missingIndices: missingIndices,
missingWordChips: Array(repeating: .empty, count: RecoveryPhraseValidationState.phraseChunks),
completion: newCompletion
)
}
default:
return state
return self
}
}
static func pickWordsFromMissingIndices(indices: [Int], phrase: RecoveryPhrase) -> [PhraseChip.Kind] {
precondition((indices.count - 1) * wordGroupSize <= phrase.words.count)
precondition((indices.count - 1) * Self.wordGroupSize <= phrase.words.count)
var words: [PhraseChip.Kind] = []
indices.enumerated().forEach({ index, position in
let realIndex = (index * wordGroupSize) + position
let realIndex = (index * Self.wordGroupSize) + position
words.append(.unassigned(word: phrase.words[realIndex]))
})
return words
@ -212,7 +199,7 @@ extension RecoveryPhraseValidationReducer {
return .none
case let .drag(wordChip, group):
state = .given(state, apply: wordChip, into: group)
state = state.apply(chip: wordChip, into: group)
return .none
case .validate:

View File

@ -28,6 +28,8 @@ class RecoveryPhraseValidationTests: XCTestCase {
let indices = [1, 0, 5, 3]
let expected = ["salute", "boil", "cancel", "pizza"].map({ PhraseChip.Kind.unassigned(word: $0) })
let result = RecoveryPhraseValidationState.pickWordsFromMissingIndices(indices: indices, phrase: phrase)
XCTAssertEqual(expected, result)
@ -73,7 +75,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
completion: [RecoveryPhraseStepCompletion(groupIndex: 1, word: "salute")]
)
let result = RecoveryPhraseValidationState.given(initialStep, apply: missingWordChips[0], into: 1)
let result = initialStep.apply(chip: missingWordChips[0], into: 1)
XCTAssertEqual(expectedStep, result)
}
@ -120,7 +122,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
completion: expectedCompletion
)
let result = RecoveryPhraseValidationState.given(initialStep, apply: missingWordChips[3], into: 0)
let result = initialStep.apply(chip: missingWordChips[3], into: 0)
XCTAssertEqual(expectedStep, result)
XCTAssertEqual(result.step, .incomplete)
@ -171,7 +173,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
]
)
let result = RecoveryPhraseValidationState.given(currentStep, apply: PhraseChip.Kind.unassigned(word: "boil"), into: 1)
let result = currentStep.apply(chip: PhraseChip.Kind.unassigned(word: "boil"), into: 1)
XCTAssertEqual(expected, result)
XCTAssertEqual(expected.step, result.step)
@ -227,7 +229,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
]
)
let result = RecoveryPhraseValidationState.given(currentStep, apply: PhraseChip.Kind.unassigned(word: "cancel"), into: 2)
let result = currentStep.apply(chip: PhraseChip.Kind.unassigned(word: "cancel"), into: 2)
XCTAssertEqual(expected, result)
}
@ -284,7 +286,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
]
)
let result = RecoveryPhraseValidationState.given(currentStep, apply: PhraseChip.Kind.unassigned(word: "pizza"), into: 3)
let result = currentStep.apply(chip: PhraseChip.Kind.unassigned(word: "pizza"), into: 3)
XCTAssertEqual(expected, result)
}
@ -442,3 +444,18 @@ class RecoveryPhraseValidationTests: XCTestCase {
XCTAssertEqual(expected, result)
}
}
extension RecoveryPhraseValidationState {
static func initial(
phrase: RecoveryPhrase,
missingIndices: [Int],
missingWordsChips: [PhraseChip.Kind]
) -> Self {
RecoveryPhraseValidationState(
phrase: phrase,
missingIndices: missingIndices,
missingWordChips: missingWordsChips,
completion: []
)
}
}