@@ -21,7 +21,7 @@ import {
21
21
tick ,
22
22
waitForAsync ,
23
23
} from '@angular/core/testing' ;
24
- import { FormsModule } from '@angular/forms' ;
24
+ import { FormControl , FormsModule , ReactiveFormsModule } from '@angular/forms' ;
25
25
import { By } from '@angular/platform-browser' ;
26
26
import { Thumb } from '@material/slider' ;
27
27
import { MatSliderModule } from './module' ;
@@ -43,7 +43,7 @@ describe('MDC-based MatSlider' , () => {
43
43
44
44
function createComponent < T > ( component : Type < T > ) : ComponentFixture < T > {
45
45
TestBed . configureTestingModule ( {
46
- imports : [ FormsModule , MatSliderModule ] ,
46
+ imports : [ FormsModule , MatSliderModule , ReactiveFormsModule ] ,
47
47
declarations : [ component ] ,
48
48
} ) . compileComponents ( ) ;
49
49
return TestBed . createComponent < T > ( component ) ;
@@ -1283,6 +1283,225 @@ describe('MDC-based MatSlider' , () => {
1283
1283
} ) ) ;
1284
1284
} ) ;
1285
1285
1286
+ describe ( 'slider as a custom form control' , ( ) => {
1287
+ let fixture : ComponentFixture < SliderWithFormControl > ;
1288
+ let testComponent : SliderWithFormControl ;
1289
+ let sliderInstance : MatSlider ;
1290
+ let inputInstance : MatSliderThumb ;
1291
+
1292
+ beforeEach ( waitForAsync ( ( ) => {
1293
+ fixture = createComponent ( SliderWithFormControl ) ;
1294
+ fixture . detectChanges ( ) ;
1295
+ testComponent = fixture . debugElement . componentInstance ;
1296
+ const sliderDebugElement = fixture . debugElement . query ( By . directive ( MatSlider ) ) ;
1297
+ sliderInstance = sliderDebugElement . componentInstance ;
1298
+ inputInstance = sliderInstance . _getInput ( Thumb . END ) ;
1299
+ } ) ) ;
1300
+
1301
+ it ( 'should not update the control when the value is updated' , ( ) => {
1302
+ expect ( testComponent . control . value ) . toBe ( 0 ) ;
1303
+ inputInstance . value = 11 ;
1304
+ fixture . detectChanges ( ) ;
1305
+ expect ( testComponent . control . value ) . toBe ( 0 ) ;
1306
+ } ) ;
1307
+
1308
+ it ( 'should update the control on mouseup' , ( ) => {
1309
+ expect ( testComponent . control . value ) . toBe ( 0 ) ;
1310
+ setValueByClick ( sliderInstance , 76 , platform . IOS ) ;
1311
+ expect ( testComponent . control . value ) . toBe ( 76 ) ;
1312
+ } ) ;
1313
+
1314
+ it ( 'should update the control on slide' , ( ) => {
1315
+ expect ( testComponent . control . value ) . toBe ( 0 ) ;
1316
+ slideToValue ( sliderInstance , 19 , Thumb . END , platform . IOS ) ;
1317
+ expect ( testComponent . control . value ) . toBe ( 19 ) ;
1318
+ } ) ;
1319
+
1320
+ it ( 'should update the value when the control is set' , ( ) => {
1321
+ expect ( inputInstance . value ) . toBe ( 0 ) ;
1322
+ testComponent . control . setValue ( 7 ) ;
1323
+ expect ( inputInstance . value ) . toBe ( 7 ) ;
1324
+ } ) ;
1325
+
1326
+ it ( 'should update the disabled state when control is disabled' , ( ) => {
1327
+ expect ( sliderInstance . disabled ) . toBe ( false ) ;
1328
+ testComponent . control . disable ( ) ;
1329
+ expect ( sliderInstance . disabled ) . toBe ( true ) ;
1330
+ } ) ;
1331
+
1332
+ it ( 'should update the disabled state when the control is enabled' , ( ) => {
1333
+ sliderInstance . disabled = true ;
1334
+ testComponent . control . enable ( ) ;
1335
+ expect ( sliderInstance . disabled ) . toBe ( false ) ;
1336
+ } ) ;
1337
+
1338
+ it ( 'should have the correct control state initially and after interaction' , ( ) => {
1339
+ let sliderControl = testComponent . control ;
1340
+
1341
+ // The control should start off valid, pristine, and untouched.
1342
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1343
+ expect ( sliderControl . pristine ) . toBe ( true ) ;
1344
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1345
+
1346
+ // After changing the value, the control should become dirty (not pristine),
1347
+ // but remain untouched.
1348
+ setValueByClick ( sliderInstance , 50 , platform . IOS ) ;
1349
+
1350
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1351
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1352
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1353
+
1354
+ // If the control has been visited due to interaction, the control should remain
1355
+ // dirty and now also be touched.
1356
+ inputInstance . blur ( ) ;
1357
+ fixture . detectChanges ( ) ;
1358
+
1359
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1360
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1361
+ expect ( sliderControl . touched ) . toBe ( true ) ;
1362
+ } ) ;
1363
+ } ) ;
1364
+
1365
+ describe ( 'slider as a custom form control' , ( ) => {
1366
+ let fixture : ComponentFixture < RangeSliderWithFormControl > ;
1367
+ let testComponent : RangeSliderWithFormControl ;
1368
+ let sliderInstance : MatSlider ;
1369
+ let startInputInstance : MatSliderThumb ;
1370
+ let endInputInstance : MatSliderThumb ;
1371
+
1372
+ beforeEach ( waitForAsync ( ( ) => {
1373
+ fixture = createComponent ( RangeSliderWithFormControl ) ;
1374
+ fixture . detectChanges ( ) ;
1375
+ testComponent = fixture . debugElement . componentInstance ;
1376
+ const sliderDebugElement = fixture . debugElement . query ( By . directive ( MatSlider ) ) ;
1377
+ sliderInstance = sliderDebugElement . componentInstance ;
1378
+ startInputInstance = sliderInstance . _getInput ( Thumb . START ) ;
1379
+ endInputInstance = sliderInstance . _getInput ( Thumb . END ) ;
1380
+ } ) ) ;
1381
+
1382
+ it ( 'should not update the start input control when the value is updated' , ( ) => {
1383
+ expect ( testComponent . startInputControl . value ) . toBe ( 0 ) ;
1384
+ startInputInstance . value = 11 ;
1385
+ fixture . detectChanges ( ) ;
1386
+ expect ( testComponent . startInputControl . value ) . toBe ( 0 ) ;
1387
+ } ) ;
1388
+
1389
+ it ( 'should not update the end input control when the value is updated' , ( ) => {
1390
+ expect ( testComponent . endInputControl . value ) . toBe ( 100 ) ;
1391
+ endInputInstance . value = 11 ;
1392
+ fixture . detectChanges ( ) ;
1393
+ expect ( testComponent . endInputControl . value ) . toBe ( 100 ) ;
1394
+ } ) ;
1395
+
1396
+ it ( 'should update the start input control on mouseup' , ( ) => {
1397
+ expect ( testComponent . startInputControl . value ) . toBe ( 0 ) ;
1398
+ setValueByClick ( sliderInstance , 20 , platform . IOS ) ;
1399
+ expect ( testComponent . startInputControl . value ) . toBe ( 20 ) ;
1400
+ } ) ;
1401
+
1402
+ it ( 'should update the end input control on mouseup' , ( ) => {
1403
+ expect ( testComponent . endInputControl . value ) . toBe ( 100 ) ;
1404
+ setValueByClick ( sliderInstance , 80 , platform . IOS ) ;
1405
+ expect ( testComponent . endInputControl . value ) . toBe ( 80 ) ;
1406
+ } ) ;
1407
+
1408
+ it ( 'should update the start input control on slide' , ( ) => {
1409
+ expect ( testComponent . startInputControl . value ) . toBe ( 0 ) ;
1410
+ slideToValue ( sliderInstance , 20 , Thumb . START , platform . IOS ) ;
1411
+ expect ( testComponent . startInputControl . value ) . toBe ( 20 ) ;
1412
+ } ) ;
1413
+
1414
+ it ( 'should update the end input control on slide' , ( ) => {
1415
+ expect ( testComponent . endInputControl . value ) . toBe ( 100 ) ;
1416
+ slideToValue ( sliderInstance , 80 , Thumb . END , platform . IOS ) ;
1417
+ expect ( testComponent . endInputControl . value ) . toBe ( 80 ) ;
1418
+ } ) ;
1419
+
1420
+ it ( 'should update the start input value when the start input control is set' , ( ) => {
1421
+ expect ( startInputInstance . value ) . toBe ( 0 ) ;
1422
+ testComponent . startInputControl . setValue ( 10 ) ;
1423
+ expect ( startInputInstance . value ) . toBe ( 10 ) ;
1424
+ } ) ;
1425
+
1426
+ it ( 'should update the end input value when the end input control is set' , ( ) => {
1427
+ expect ( endInputInstance . value ) . toBe ( 100 ) ;
1428
+ testComponent . endInputControl . setValue ( 90 ) ;
1429
+ expect ( endInputInstance . value ) . toBe ( 90 ) ;
1430
+ } ) ;
1431
+
1432
+ it ( 'should update the disabled state if the start input control is disabled' , ( ) => {
1433
+ expect ( sliderInstance . disabled ) . toBe ( false ) ;
1434
+ testComponent . startInputControl . disable ( ) ;
1435
+ expect ( sliderInstance . disabled ) . toBe ( true ) ;
1436
+ } ) ;
1437
+
1438
+ it ( 'should update the disabled state if the end input control is disabled' , ( ) => {
1439
+ expect ( sliderInstance . disabled ) . toBe ( false ) ;
1440
+ testComponent . endInputControl . disable ( ) ;
1441
+ expect ( sliderInstance . disabled ) . toBe ( true ) ;
1442
+ } ) ;
1443
+
1444
+ it ( 'should update the disabled state when both input controls are enabled' , ( ) => {
1445
+ sliderInstance . disabled = true ;
1446
+ testComponent . startInputControl . enable ( ) ;
1447
+ expect ( sliderInstance . disabled ) . toBe ( true ) ;
1448
+ testComponent . endInputControl . enable ( ) ;
1449
+ expect ( sliderInstance . disabled ) . toBe ( false ) ;
1450
+ } ) ;
1451
+
1452
+ it ( 'should have the correct start input control state initially and after interaction' , ( ) => {
1453
+ let sliderControl = testComponent . startInputControl ;
1454
+
1455
+ // The control should start off valid, pristine, and untouched.
1456
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1457
+ expect ( sliderControl . pristine ) . toBe ( true ) ;
1458
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1459
+
1460
+ // After changing the value, the control should become dirty (not pristine),
1461
+ // but remain untouched.
1462
+ setValueByClick ( sliderInstance , 25 , platform . IOS ) ;
1463
+
1464
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1465
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1466
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1467
+
1468
+ // If the control has been visited due to interaction, the control should remain
1469
+ // dirty and now also be touched.
1470
+ startInputInstance . blur ( ) ;
1471
+ fixture . detectChanges ( ) ;
1472
+
1473
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1474
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1475
+ expect ( sliderControl . touched ) . toBe ( true ) ;
1476
+ } ) ;
1477
+
1478
+ it ( 'should have the correct start input control state initially and after interaction' , ( ) => {
1479
+ let sliderControl = testComponent . endInputControl ;
1480
+
1481
+ // The control should start off valid, pristine, and untouched.
1482
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1483
+ expect ( sliderControl . pristine ) . toBe ( true ) ;
1484
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1485
+
1486
+ // After changing the value, the control should become dirty (not pristine),
1487
+ // but remain untouched.
1488
+ setValueByClick ( sliderInstance , 75 , platform . IOS ) ;
1489
+
1490
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1491
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1492
+ expect ( sliderControl . touched ) . toBe ( false ) ;
1493
+
1494
+ // If the control has been visited due to interaction, the control should remain
1495
+ // dirty and now also be touched.
1496
+ endInputInstance . blur ( ) ;
1497
+ fixture . detectChanges ( ) ;
1498
+
1499
+ expect ( sliderControl . valid ) . toBe ( true ) ;
1500
+ expect ( sliderControl . pristine ) . toBe ( false ) ;
1501
+ expect ( sliderControl . touched ) . toBe ( true ) ;
1502
+ } ) ;
1503
+ } ) ;
1504
+
1286
1505
describe ( 'slider with a two-way binding' , ( ) => {
1287
1506
let fixture : ComponentFixture < SliderWithTwoWayBinding > ;
1288
1507
let testComponent : SliderWithTwoWayBinding ;
@@ -1559,6 +1778,28 @@ class RangeSliderWithNgModel {
1559
1778
endVal : number | undefined = 100 ;
1560
1779
}
1561
1780
1781
+ @Component ( {
1782
+ template : `
1783
+ <mat-slider>
1784
+ <input [formControl]="control" matSliderThumb>
1785
+ </mat-slider>` ,
1786
+ } )
1787
+ class SliderWithFormControl {
1788
+ control = new FormControl ( 0 ) ;
1789
+ }
1790
+
1791
+ @Component ( {
1792
+ template : `
1793
+ <mat-slider>
1794
+ <input [formControl]="startInputControl" matSliderStartThumb>
1795
+ <input [formControl]="endInputControl" matSliderEndThumb>
1796
+ </mat-slider>` ,
1797
+ } )
1798
+ class RangeSliderWithFormControl {
1799
+ startInputControl = new FormControl ( 0 ) ;
1800
+ endInputControl = new FormControl ( 100 ) ;
1801
+ }
1802
+
1562
1803
@Component ( {
1563
1804
template : `
1564
1805
<mat-slider>
0 commit comments