Skip to content

Commit b2e38fe

Browse files
committed
Test more cases for unregister method
1 parent 458225f commit b2e38fe

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed

Sources/FormHook/Form.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class FormControl<FieldName> where FieldName: Hashable {
4242
names.forEach { fields[$0] = nil }
4343
}
4444
names.forEach {
45-
if let field = fields[$0] as? Field<FieldName>, field.options.shouldUnregister {
45+
if fields[$0]?.shouldUnregister ?? false {
4646
fields[$0] = nil
4747
}
4848
}
@@ -404,6 +404,10 @@ private extension FormControl {
404404
self.value = control.computeValueBinding(name: name, defaultValue: options.defaultValue)
405405
}
406406

407+
var shouldUnregister: Bool {
408+
options.shouldUnregister
409+
}
410+
407411
func computeMessages() async -> (Bool, [String]) {
408412
await options.rules.computeMessage(value: value.wrappedValue)
409413
}

Sources/FormHook/Hook/UseForm.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public struct FormOption<FieldName> where FieldName: Hashable {
4040
var reValidateMode: ReValidateMode
4141
let resolver: Resolver<FieldName>?
4242
let context: Any?
43-
let shouldUnregister: Bool
44-
let delayError: Bool
43+
var shouldUnregister: Bool
44+
var delayError: Bool
4545

4646
init(mode: Mode,
4747
reValidateMode: ReValidateMode,

Sources/FormHook/Types.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,6 @@ public struct FieldState {
202202
}
203203

204204
protocol FieldProtocol {
205+
var shouldUnregister: Bool { get }
205206
func computeMessages() async -> (Bool, [String])
206207
}

Tests/FormHookTests/FormHookTests.swift

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,45 @@ final class FormHookTests: QuickSpec {
8484
}
8585

8686
func unregisterSpecs() {
87+
describe("Form Control with shouldUnregister equals false registers a field \"a\" with a default value") {
88+
var formControl: FormControl<TestFieldName>!
89+
var aValidator: MockValidator<String, Bool>!
90+
let testDefaultValue = "%^$#"
91+
92+
beforeEach {
93+
var formState: FormState<TestFieldName> = .init()
94+
let options = FormOption<TestFieldName>(
95+
mode: .onSubmit,
96+
reValidateMode: .onChange,
97+
resolver: nil,
98+
context: nil,
99+
shouldUnregister: false,
100+
delayError: true
101+
)
102+
formControl = .init(options: options, formState: .init(
103+
get: { formState },
104+
set: { formState = $0 }
105+
))
106+
107+
aValidator = MockValidator<String, Bool>(result: true)
108+
_ = formControl.register(name: .a, options: .init(rules: aValidator!, defaultValue: testDefaultValue))
109+
}
110+
111+
context("then unregister field \"a\"") {
112+
context("key \"a\" hasn't been configured") {
113+
beforeEach {
114+
await formControl.unregister(name: .a)
115+
}
116+
117+
it("value of key \"a\" will be removed") {
118+
let formState = await formControl.formState
119+
expect(formState.defaultValues[.a]).to(beNil())
120+
expect(formState.formValues[.a]).to(beNil())
121+
}
122+
}
123+
}
124+
}
125+
87126
describe("Form Control registers a field \"a\" with a default value") {
88127
var formControl: FormControl<TestFieldName>!
89128
var aValidator: MockValidator<String, Bool>!
@@ -1309,6 +1348,7 @@ final class FormHookTests: QuickSpec {
13091348
var bValidator: MockValidator<String, Bool>!
13101349
let aDefaultValue = "%^$#"
13111350
let bDefaultValue = "%^$#*("
1351+
var aBinder: FieldRegistration<String>!
13121352

13131353
beforeEach {
13141354
var formState: FormState<TestFieldName> = .init()
@@ -1326,7 +1366,7 @@ final class FormHookTests: QuickSpec {
13261366
))
13271367

13281368
aValidator = MockValidator<String, Bool>(result: true)
1329-
_ = formControl.register(name: .a, options: .init(rules: aValidator!, defaultValue: aDefaultValue))
1369+
aBinder = formControl.register(name: .a, options: .init(rules: aValidator!, defaultValue: aDefaultValue))
13301370

13311371
bValidator = MockValidator<String, Bool>(result: true)
13321372
_ = formControl.register(name: .b, options: .init(rules: bValidator!, defaultValue: bDefaultValue))
@@ -1409,6 +1449,79 @@ final class FormHookTests: QuickSpec {
14091449
}
14101450
}
14111451
}
1452+
1453+
context("changes mode to .onChange") {
1454+
beforeEach {
1455+
formControl.options.mode = .onChange
1456+
}
1457+
1458+
context("field \"a\" changes its value, and will be invalid") {
1459+
beforeEach {
1460+
aValidator.result = false
1461+
aValidator.messages = ["Failed to validate a"]
1462+
aBinder.wrappedValue = "a"
1463+
await formControl.syncFormState()
1464+
}
1465+
1466+
it("field \"a\" is triggered, and is invalid") {
1467+
try? await Task.sleep(nanoseconds: 2_000_000)
1468+
1469+
let fieldState = await formControl.getFieldState(name: .a)
1470+
expect(fieldState.isInvalid) == true
1471+
1472+
let formState = await formControl.formState
1473+
expect(formState.errors[.a]) == ["Failed to validate a"]
1474+
}
1475+
}
1476+
}
1477+
1478+
context("key \"a\" has been already invalid, and validation of \"a\" returns true") {
1479+
beforeEach {
1480+
formControl.instantFormState.errors.setMessages(
1481+
name: .a, messages: [
1482+
"Failed to validate a"
1483+
],
1484+
isValid: false
1485+
)
1486+
aValidator.result = true
1487+
aValidator.messages = []
1488+
await formControl.syncFormState()
1489+
}
1490+
1491+
context("changes reValidationMode to .onChange, and key \"a\" changes its value") {
1492+
beforeEach {
1493+
formControl.options.reValidateMode = .onChange
1494+
aBinder.wrappedValue = "a"
1495+
}
1496+
1497+
it("field \"a\" is triggered, and is valid") {
1498+
try? await Task.sleep(nanoseconds: 2_000_000)
1499+
1500+
let formState = await formControl.formState
1501+
expect(formState.errors[.a]) == []
1502+
1503+
let fieldState = await formControl.getFieldState(name: .a)
1504+
expect(fieldState.isInvalid) == false
1505+
}
1506+
}
1507+
1508+
context("changes reValidationMode to .onSubmit, and key \"a\" changes its value") {
1509+
beforeEach {
1510+
formControl.options.reValidateMode = .onSubmit
1511+
aBinder.wrappedValue = "a"
1512+
}
1513+
1514+
it("field \"a\" is triggered, and is still invalid") {
1515+
try? await Task.sleep(nanoseconds: 2_000_000)
1516+
1517+
let fieldState = await formControl.getFieldState(name: .a)
1518+
expect(fieldState.isInvalid) == true
1519+
1520+
let formState = await formControl.formState
1521+
expect(formState.errors[.a]) == ["Failed to validate a"]
1522+
}
1523+
}
1524+
}
14121525
}
14131526
}
14141527
}

0 commit comments

Comments
 (0)