@@ -19,6 +19,7 @@ final class FormHookTests: QuickSpec {
1919 setValueSpecs ( )
2020 handleSubmitSpecs ( )
2121 triggerSpecs ( )
22+ resolverSpecs ( )
2223 }
2324
2425 func registerSpecs( ) {
@@ -292,6 +293,67 @@ final class FormHookTests: QuickSpec {
292293 }
293294
294295 func resetSingleFieldSpecs( ) {
296+ describe ( " Form Control registered field \" a \" and \" b \" with non-nil resolver " ) {
297+ var formControl : FormControl < TestFieldName > !
298+ var aValidator : MockValidator < String , Bool > !
299+ var bValidator : MockValidator < String , Bool > !
300+ let aDefaultValue = " %^$# "
301+ let bDefaultValue = " %^$#*( "
302+
303+ let resolverProxy = ResolverProxy < TestFieldName > ( value: [
304+ . a: aDefaultValue,
305+ . b: bDefaultValue
306+ ] )
307+
308+ beforeEach {
309+ var formState : FormState < TestFieldName > = . init( )
310+ let options = FormOption < TestFieldName > (
311+ mode: . onSubmit,
312+ reValidateMode: . onChange,
313+ resolver: resolverProxy. resolver ( values: context: fieldNames: ) ,
314+ context: nil ,
315+ shouldUnregister: true ,
316+ delayError: true
317+ )
318+ formControl = . init( options: options, formState: . init(
319+ get: { formState } ,
320+ set: { formState = $0 }
321+ ) )
322+
323+ aValidator = MockValidator < String , Bool > ( result: true )
324+ _ = formControl. register ( name: . a, options: . init( rules: aValidator!, defaultValue: aDefaultValue) )
325+
326+ bValidator = MockValidator < String , Bool > ( result: true )
327+ _ = formControl. register ( name: . b, options: . init( rules: bValidator!, defaultValue: bDefaultValue) )
328+ }
329+
330+ context ( " formState is invalid " ) {
331+ beforeEach {
332+ formControl. instantFormState. isValid = false
333+ formControl. instantFormState. errors. setMessages (
334+ name: . a,
335+ messages: [
336+ " Failed to validate a "
337+ ] ,
338+ isValid: false
339+ )
340+ await formControl. syncFormState ( )
341+ }
342+
343+ context ( " reset field \" b \" with default option " ) {
344+ beforeEach {
345+ await formControl. reset ( name: . b)
346+ }
347+
348+ it ( " field \" a \" is still invalid " ) {
349+ let fieldState = await formControl. getFieldState ( name: . a)
350+ expect ( fieldState. isInvalid) == true
351+ expect ( fieldState. error) == [ " Failed to validate a " ]
352+ }
353+ }
354+ }
355+ }
356+
295357 describe ( " Form Control registered field \" a \" " ) {
296358 var formControl : FormControl < TestFieldName > !
297359 var aValidator : MockValidator < String , Bool > !
@@ -1524,4 +1586,156 @@ final class FormHookTests: QuickSpec {
15241586 }
15251587 }
15261588 }
1589+
1590+ func resolverSpecs( ) {
1591+ describe ( " Form Control registered field \" a \" and \" b \" with non-nil resolver " ) {
1592+ var formControl : FormControl < TestFieldName > !
1593+ var aValidator : MockValidator < String , Bool > !
1594+ var bValidator : MockValidator < String , Bool > !
1595+ let aDefaultValue = " %^$# "
1596+ let bDefaultValue = " %^$#*( "
1597+
1598+ let resolverProxy = ResolverProxy < TestFieldName > ( value: [
1599+ . a: aDefaultValue,
1600+ . b: bDefaultValue
1601+ ] )
1602+
1603+ beforeEach {
1604+ var formState : FormState < TestFieldName > = . init( )
1605+ let options = FormOption < TestFieldName > (
1606+ mode: . onSubmit,
1607+ reValidateMode: . onChange,
1608+ resolver: resolverProxy. resolver ( values: context: fieldNames: ) ,
1609+ context: nil ,
1610+ shouldUnregister: true ,
1611+ delayError: true
1612+ )
1613+ formControl = . init( options: options, formState: . init(
1614+ get: { formState } ,
1615+ set: { formState = $0 }
1616+ ) )
1617+
1618+ aValidator = MockValidator < String , Bool > ( result: true )
1619+ _ = formControl. register ( name: . a, options: . init( rules: aValidator!, defaultValue: aDefaultValue) )
1620+
1621+ bValidator = MockValidator < String , Bool > ( result: true )
1622+ _ = formControl. register ( name: . b, options: . init( rules: bValidator!, defaultValue: bDefaultValue) )
1623+ }
1624+
1625+ context ( " resolver indicates all fields are valid " ) {
1626+ context ( " validation of \" a \" returns failure " ) {
1627+ beforeEach {
1628+ aValidator. result = false
1629+ aValidator. messages = [ " Failed to validate a " ]
1630+ }
1631+
1632+ context ( " reset field \" a \" with default options " ) {
1633+ beforeEach {
1634+ await formControl. reset ( name: . a)
1635+ }
1636+
1637+ it ( " all fields are valid " ) {
1638+ let formState = await formControl. formState
1639+ expect ( formState. isValid) == true
1640+ expect ( formState. errors [ . a] ) . to ( beNil ( ) )
1641+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1642+ }
1643+ }
1644+
1645+ context ( " submit the form " ) {
1646+ beforeEach {
1647+ try ? await formControl. handleSubmit ( onValid: { _, _ in } )
1648+ }
1649+
1650+ it ( " all fields are valid " ) {
1651+ let formState = await formControl. formState
1652+ expect ( formState. isValid) == true
1653+ expect ( formState. errors [ . a] ) . to ( beNil ( ) )
1654+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1655+ }
1656+ }
1657+
1658+ context ( " trigger field \" a \" " ) {
1659+ beforeEach {
1660+ await formControl. trigger ( name: . a)
1661+ }
1662+
1663+ it ( " all fields are valid " ) {
1664+ let formState = await formControl. formState
1665+ expect ( formState. isValid) == true
1666+ expect ( formState. errors [ . a] ) . to ( beNil ( ) )
1667+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1668+ }
1669+ }
1670+ }
1671+ }
1672+
1673+ context ( " resolver indicates field \" a \" is invalid " ) {
1674+ beforeEach {
1675+ let errors : FormError < TestFieldName > = . init(
1676+ errorFields: [ . a] ,
1677+ messages: [
1678+ . a: [ " Failed to validate a " ]
1679+ ]
1680+ )
1681+ resolverProxy. result = . failure( errors)
1682+ }
1683+
1684+ context ( " submit the form " ) {
1685+ beforeEach {
1686+ try ? await formControl. handleSubmit ( onValid: { _, _ in } )
1687+ }
1688+
1689+ it ( " field \" a \" is invalid and \" b \" isn't " ) {
1690+ let formState = await formControl. formState
1691+ expect ( formState. isValid) == false
1692+ expect ( formState. errors [ . a] ) == [ " Failed to validate a " ]
1693+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1694+ }
1695+ }
1696+
1697+ context ( " trigger field \" a \" " ) {
1698+ beforeEach {
1699+ await formControl. trigger ( name: . a)
1700+ }
1701+
1702+ it ( " field \" a \" is invalid and \" b \" isn't " ) {
1703+ let formState = await formControl. formState
1704+ expect ( formState. isValid) == false
1705+ expect ( formState. errors [ . a] ) == [ " Failed to validate a " ]
1706+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1707+ }
1708+ }
1709+
1710+ context ( " reset field \" a \" with default options " ) {
1711+ beforeEach {
1712+ await formControl. reset ( name: . a)
1713+ }
1714+
1715+ it ( " field \" a \" is invalid and \" b \" isn't " ) {
1716+ let formState = await formControl. formState
1717+ expect ( formState. isValid) == false
1718+ expect ( formState. errors [ . a] ) == [ " Failed to validate a " ]
1719+ expect ( formState. errors [ . b] ) . to ( beNil ( ) )
1720+ }
1721+ }
1722+ }
1723+ }
1724+ }
1725+ }
1726+
1727+ private class ResolverProxy < FieldName> where FieldName: Hashable {
1728+ var result : Result < ResolverValue < FieldName > , ResolverError < FieldName > >
1729+
1730+ init ( value: ResolverValue < FieldName > ) {
1731+ self . result = . success( value)
1732+ }
1733+
1734+ init ( error: ResolverError < FieldName > ) {
1735+ self . result = . failure( error)
1736+ }
1737+
1738+ func resolver( values: ResolverValue < FieldName > , context: Any ? , fieldNames: [ FieldName ] ) async -> Result < ResolverValue < FieldName > , ResolverError < FieldName > > {
1739+ result
1740+ }
15271741}
0 commit comments