@@ -16,13 +16,25 @@ TestBed.initTestEnvironment(
1616@Component ( {
1717 template : `
1818 <form [formGroup]="form">
19- <input formControlName="prop">
20- <div ngxErrors="prop">
21- <div ngxError="required" [when]="dirty">
19+ <input
20+ class="prop"
21+ formControlName="prop"
22+ [ngClass]="{
23+ requiredVisibleAtRuntime: prop.hasError('required'),
24+ requiredVisibleWhenDirty: prop.hasError('required', ['dirty']),
25+ requiredVisibleWhenDirtyTouched: prop.hasError('required', ['dirty', 'touched']),
26+ visibleAnyErrorDirtyTouched: prop.hasError('*', ['dirty', 'touched'])
27+ }">
28+ <div class="errorProps">
29+ <div class="errorProp1">{{ prop.errors | json }}</div>
30+ <div class="errorProp2">{{ prop.hasErrors | json }}</div>
31+ </div>
32+ <div ngxErrors="prop" #prop="ngxErrors">
33+ <div ngxError="required" when="dirty">
2234 Required
2335 </div>
24- <div [ngxError]="['minlength', 'maxlength']" [when]="['dirty', 'touched']">
25- 5 characters minimum, 10 characters maximum
36+ <div class="errorMinLength" [ngxError]="['minlength', 'maxlength']" [when]="['dirty', 'touched']">
37+ {{ prop.getError('minlength')?.requiredLength }} characters minimum, {{ prop.getError('maxlength')?.requiredLength }} characters maximum
2638 </div>
2739 </div>
2840 </form>
@@ -66,31 +78,40 @@ describe('Directives: ngxErrors, ngxError, when', () => {
6678
6779 } ) ;
6880
69- it ( 'should show ngxError[required] when required is true' , async ( ) => {
81+ it ( 'should show ngxError[required] when required is true and dirty ' , async ( done ) => {
7082
7183 const element = el . queryAll ( By . directive ( NgxErrorDirective ) ) [ 0 ] ;
7284
85+ expect ( component . form . get ( 'prop' ) . dirty ) . toBe ( false ) ;
7386 component . form . patchValue ( { prop : 'ngxErrors' } ) ;
87+ component . form . get ( 'prop' ) . markAsDirty ( ) ;
7488 fixture . detectChanges ( ) ;
7589 await fixture . whenStable ( ) ;
90+ expect ( component . form . get ( 'prop' ) . dirty ) . toBe ( true ) ;
7691 expect ( element . nativeElement . hasAttribute ( 'hidden' ) ) . toBe ( true ) ;
77- expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( true ) ;
92+ expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( false ) ;
7893
79- component . form . patchValue ( { prop : '' } ) ;
94+ component . form . patchValue ( { prop : null } ) ;
8095 fixture . detectChanges ( ) ;
8196 await fixture . whenStable ( ) ;
8297 expect ( element . nativeElement . hasAttribute ( 'hidden' ) ) . toBe ( false ) ;
83- expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( false ) ;
98+ expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( true ) ;
99+
100+ done ( ) ;
84101
85102 } ) ;
86103
87- it ( 'should show ngxError[minlength] or ngxError[ maxlength] when either are true' , async ( ) => {
104+ it ( 'should show ngxError[minlength | maxlength] when either are true, touched and dirty ' , async ( done ) => {
88105
89106 const element = el . queryAll ( By . directive ( NgxErrorDirective ) ) [ 1 ] ;
107+ expect ( component . form . get ( 'prop' ) . dirty ) . toBe ( false ) ;
90108 expect ( component . form . get ( 'prop' ) . touched ) . toBe ( false ) ;
91109 component . form . patchValue ( { prop : 'ngxErrors' } ) ;
110+ component . form . get ( 'prop' ) . markAsDirty ( ) ;
111+ component . form . get ( 'prop' ) . markAsTouched ( ) ;
92112 fixture . detectChanges ( ) ;
93113 await fixture . whenStable ( ) ;
114+ expect ( component . form . get ( 'prop' ) . dirty ) . toBe ( true ) ;
94115 expect ( component . form . get ( 'prop' ) . touched ) . toBe ( true ) ;
95116 expect ( element . nativeElement . hasAttribute ( 'hidden' ) ) . toBe ( true ) ;
96117 expect ( component . form . get ( 'prop' ) . hasError ( 'minlength' ) ) . toBe ( false ) ;
@@ -110,6 +131,68 @@ describe('Directives: ngxErrors, ngxError, when', () => {
110131 expect ( component . form . get ( 'prop' ) . hasError ( 'minlength' ) ) . toBe ( false ) ;
111132 expect ( component . form . get ( 'prop' ) . hasError ( 'maxlength' ) ) . toBe ( true ) ;
112133
134+ done ( ) ;
135+
136+ } ) ;
137+
138+ it ( 'should provide a template ref API via ngxErrors exportAs' , async ( done ) => {
139+ await fixture . whenStable ( ) ;
140+
141+ fixture . changeDetectorRef . markForCheck ( ) ;
142+ fixture . detectChanges ( ) ;
143+ await fixture . whenStable ( ) ;
144+
145+ const element = el . query ( By . css ( 'input.prop' ) ) ;
146+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleAtRuntime' ) ) . toBe ( true ) ;
147+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirty' ) ) . toBe ( false ) ;
148+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirtyTouched' ) ) . toBe ( false ) ;
149+
150+ component . form . patchValue ( { prop : 'ngxErrors' } ) ;
151+ component . form . get ( 'prop' ) . markAsDirty ( ) ;
152+ component . form . get ( 'prop' ) . markAsTouched ( ) ;
153+ fixture . detectChanges ( ) ;
154+ await fixture . whenStable ( ) ;
155+ expect ( component . form . get ( 'prop' ) . dirty ) . toBe ( true ) ;
156+ expect ( component . form . get ( 'prop' ) . touched ) . toBe ( true ) ;
157+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleAtRuntime' ) ) . toBe ( false ) ;
158+ component . form . patchValue ( { prop : '' } ) ;
159+ fixture . detectChanges ( ) ;
160+ await fixture . whenStable ( ) ;
161+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirty' ) ) . toBe ( true ) ;
162+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirtyTouched' ) ) . toBe ( true ) ;
163+
164+ component . form . patchValue ( { prop : 'ngx' } ) ;
165+ fixture . detectChanges ( ) ;
166+ await fixture . whenStable ( ) ;
167+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleAtRuntime' ) ) . toBe ( false ) ;
168+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirty' ) ) . toBe ( false ) ;
169+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirtyTouched' ) ) . toBe ( false ) ;
170+ expect ( element . nativeElement . classList . contains ( 'visibleAnyErrorDirtyTouched' ) ) . toBe ( true ) ;
171+ expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( false ) ;
172+ expect ( component . form . get ( 'prop' ) . hasError ( 'minlength' ) ) . toBe ( true ) ;
173+ expect ( component . form . get ( 'prop' ) . hasError ( 'maxlength' ) ) . toBe ( false ) ;
174+ expect ( el . query ( By . css ( '.errorMinLength' ) ) . nativeElement . textContent ) . toContain ( '5 characters minimum' ) ;
175+
176+ component . form . patchValue ( { prop : 'ngxErrors!!!!!' } ) ;
177+ fixture . detectChanges ( ) ;
178+ await fixture . whenStable ( ) ;
179+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleAtRuntime' ) ) . toBe ( false ) ;
180+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirty' ) ) . toBe ( false ) ;
181+ expect ( element . nativeElement . classList . contains ( 'requiredVisibleWhenDirtyTouched' ) ) . toBe ( false ) ;
182+ expect ( element . nativeElement . classList . contains ( 'visibleAnyErrorDirtyTouched' ) ) . toBe ( true ) ;
183+ expect ( component . form . get ( 'prop' ) . hasError ( 'required' ) ) . toBe ( false ) ;
184+ expect ( component . form . get ( 'prop' ) . hasError ( 'minlength' ) ) . toBe ( false ) ;
185+ expect ( component . form . get ( 'prop' ) . hasError ( 'maxlength' ) ) . toBe ( true ) ;
186+ expect ( el . query ( By . css ( '.errorMinLength' ) ) . nativeElement . textContent ) . toContain ( '10 characters maximum' ) ;
187+
188+ const parse = ( name ) => JSON . parse ( el . query ( By . css ( name ) ) . nativeElement . textContent ) ;
189+
190+ expect ( parse ( '.errorProp1' ) . maxlength . requiredLength ) . toBe ( 10 ) ;
191+ expect ( parse ( '.errorProp1' ) . maxlength . actualLength ) . toBe ( 14 ) ;
192+ expect ( parse ( '.errorProp2' ) ) . toBe ( true ) ;
193+
194+ done ( ) ;
195+
113196 } ) ;
114197
115198} ) ;
0 commit comments