Skip to content

Commit

Permalink
fix(slider): slider module depends on forms module (#5578)
Browse files Browse the repository at this point in the history
* The slider module should not not import the `FormsModule` since the slider is designed to work without forms as well.
  • Loading branch information
devversion authored and mmalerba committed Jul 9, 2017
1 parent b31a304 commit c14978b
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 156 deletions.
3 changes: 1 addition & 2 deletions src/lib/slider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
import {NgModule} from '@angular/core';
import {HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {MdCommonModule, GestureConfig, StyleModule} from '../core';
import {MdSlider} from './slider';
import {BidiModule} from '../core/bidi/index';


@NgModule({
imports: [CommonModule, FormsModule, MdCommonModule, StyleModule, BidiModule],
imports: [CommonModule, MdCommonModule, StyleModule, BidiModule],
exports: [MdSlider, MdCommonModule],
declarations: [MdSlider],
providers: [{provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig}]
Expand Down
328 changes: 174 additions & 154 deletions src/lib/slider/slider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import {
} from '../core/keyboard/keycodes';
import {dispatchKeyboardEvent, dispatchMouseEvent} from '@angular/cdk/testing';


describe('MdSlider', () => {
describe('MdSlider without forms', () => {
let gestureConfig: TestGestureConfig;

beforeEach(async(() => {
Expand All @@ -35,8 +34,6 @@ describe('MdSlider', () => {
SliderWithSetTickInterval,
SliderWithThumbLabel,
SliderWithOneWayBinding,
SliderWithFormControl,
SliderWithNgModel,
SliderWithValueSmallerThanMin,
SliderWithValueGreaterThanMax,
SliderWithChangeHandler,
Expand Down Expand Up @@ -552,156 +549,6 @@ describe('MdSlider', () => {
});
});

describe('slider as a custom form control', () => {
let fixture: ComponentFixture<SliderWithFormControl>;
let sliderDebugElement: DebugElement;
let sliderNativeElement: HTMLElement;
let sliderInstance: MdSlider;
let sliderWrapperElement: HTMLElement;
let testComponent: SliderWithFormControl;

beforeEach(() => {
fixture = TestBed.createComponent(SliderWithFormControl);
fixture.detectChanges();

testComponent = fixture.debugElement.componentInstance;

sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider));
sliderNativeElement = sliderDebugElement.nativeElement;
sliderInstance = sliderDebugElement.injector.get<MdSlider>(MdSlider);
sliderWrapperElement = <HTMLElement>sliderNativeElement.querySelector('.mat-slider-wrapper');
});

it('should not update the control when the value is updated', () => {
expect(testComponent.control.value).toBe(0);

sliderInstance.value = 11;
fixture.detectChanges();

expect(testComponent.control.value).toBe(0);
});

it('should update the control on click', () => {
expect(testComponent.control.value).toBe(0);

dispatchClickEventSequence(sliderNativeElement, 0.76);
fixture.detectChanges();

expect(testComponent.control.value).toBe(76);
});

it('should update the control on slide', () => {
expect(testComponent.control.value).toBe(0);

dispatchSlideEventSequence(sliderNativeElement, 0, 0.19, gestureConfig);
fixture.detectChanges();

expect(testComponent.control.value).toBe(19);
});

it('should update the value when the control is set', () => {
expect(sliderInstance.value).toBe(0);

testComponent.control.setValue(7);
fixture.detectChanges();

expect(sliderInstance.value).toBe(7);
});

it('should update the disabled state when control is disabled', () => {
expect(sliderInstance.disabled).toBe(false);

testComponent.control.disable();
fixture.detectChanges();

expect(sliderInstance.disabled).toBe(true);
});

it('should update the disabled state when the control is enabled', () => {
sliderInstance.disabled = true;

testComponent.control.enable();
fixture.detectChanges();

expect(sliderInstance.disabled).toBe(false);
});

it('should have the correct control state initially and after interaction', () => {
let sliderControl = testComponent.control;

// The control should start off valid, pristine, and untouched.
expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(true);
expect(sliderControl.touched).toBe(false);

// After changing the value, the control should become dirty (not pristine),
// but remain untouched.
dispatchClickEventSequence(sliderNativeElement, 0.5);
fixture.detectChanges();

expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(false);
expect(sliderControl.touched).toBe(false);

// If the control has been visited due to interaction, the control should remain
// dirty and now also be touched.
sliderInstance._onBlur();
fixture.detectChanges();

expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(false);
expect(sliderControl.touched).toBe(true);
});
});

describe('slider with ngModel', () => {
let fixture: ComponentFixture<SliderWithNgModel>;
let sliderDebugElement: DebugElement;
let sliderNativeElement: HTMLElement;
let sliderInstance: MdSlider;
let sliderWrapperElement: HTMLElement;
let testComponent: SliderWithNgModel;

beforeEach(() => {
fixture = TestBed.createComponent(SliderWithNgModel);
fixture.detectChanges();

testComponent = fixture.debugElement.componentInstance;

sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider));
sliderNativeElement = sliderDebugElement.nativeElement;
sliderInstance = sliderDebugElement.injector.get<MdSlider>(MdSlider);
sliderWrapperElement = <HTMLElement>sliderNativeElement.querySelector('.mat-slider-wrapper');
});

it('should update the model on click', () => {
expect(testComponent.val).toBe(0);

dispatchClickEventSequence(sliderNativeElement, 0.76);
fixture.detectChanges();

expect(testComponent.val).toBe(76);
});

it('should update the model on slide', () => {
expect(testComponent.val).toBe(0);

dispatchSlideEventSequence(sliderNativeElement, 0, 0.19, gestureConfig);
fixture.detectChanges();

expect(testComponent.val).toBe(19);
});

it('should update the model on keydown', () => {
expect(testComponent.val).toBe(0);

dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
fixture.detectChanges();

expect(testComponent.val).toBe(1);
});
});

describe('slider with value property binding', () => {
let fixture: ComponentFixture<SliderWithOneWayBinding>;
let sliderDebugElement: DebugElement;
Expand Down Expand Up @@ -1225,6 +1072,179 @@ describe('MdSlider', () => {
});
});

describe('MdSlider with forms module', () => {
let gestureConfig: TestGestureConfig;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdSliderModule, ReactiveFormsModule, FormsModule, BidiModule],
declarations: [
SliderWithFormControl,
SliderWithNgModel,
],
providers: [
{provide: HAMMER_GESTURE_CONFIG, useFactory: () => {
gestureConfig = new TestGestureConfig();
return gestureConfig;
}}
],
});

TestBed.compileComponents();
}));

describe('slider with ngModel', () => {
let fixture: ComponentFixture<SliderWithNgModel>;
let sliderDebugElement: DebugElement;
let sliderNativeElement: HTMLElement;
let sliderInstance: MdSlider;
let sliderWrapperElement: HTMLElement;
let testComponent: SliderWithNgModel;

beforeEach(() => {
fixture = TestBed.createComponent(SliderWithNgModel);
fixture.detectChanges();

testComponent = fixture.debugElement.componentInstance;

sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider));
sliderNativeElement = sliderDebugElement.nativeElement;
sliderInstance = sliderDebugElement.injector.get<MdSlider>(MdSlider);
sliderWrapperElement = <HTMLElement>sliderNativeElement.querySelector('.mat-slider-wrapper');
});

it('should update the model on click', () => {
expect(testComponent.val).toBe(0);

dispatchClickEventSequence(sliderNativeElement, 0.76);
fixture.detectChanges();

expect(testComponent.val).toBe(76);
});

it('should update the model on slide', () => {
expect(testComponent.val).toBe(0);

dispatchSlideEventSequence(sliderNativeElement, 0, 0.19, gestureConfig);
fixture.detectChanges();

expect(testComponent.val).toBe(19);
});

it('should update the model on keydown', () => {
expect(testComponent.val).toBe(0);

dispatchKeyboardEvent(sliderNativeElement, 'keydown', UP_ARROW);
fixture.detectChanges();

expect(testComponent.val).toBe(1);
});
});

describe('slider as a custom form control', () => {
let fixture: ComponentFixture<SliderWithFormControl>;
let sliderDebugElement: DebugElement;
let sliderNativeElement: HTMLElement;
let sliderInstance: MdSlider;
let sliderWrapperElement: HTMLElement;
let testComponent: SliderWithFormControl;

beforeEach(() => {
fixture = TestBed.createComponent(SliderWithFormControl);
fixture.detectChanges();

testComponent = fixture.debugElement.componentInstance;

sliderDebugElement = fixture.debugElement.query(By.directive(MdSlider));
sliderNativeElement = sliderDebugElement.nativeElement;
sliderInstance = sliderDebugElement.injector.get<MdSlider>(MdSlider);
sliderWrapperElement = <HTMLElement>sliderNativeElement.querySelector('.mat-slider-wrapper');
});

it('should not update the control when the value is updated', () => {
expect(testComponent.control.value).toBe(0);

sliderInstance.value = 11;
fixture.detectChanges();

expect(testComponent.control.value).toBe(0);
});

it('should update the control on click', () => {
expect(testComponent.control.value).toBe(0);

dispatchClickEventSequence(sliderNativeElement, 0.76);
fixture.detectChanges();

expect(testComponent.control.value).toBe(76);
});

it('should update the control on slide', () => {
expect(testComponent.control.value).toBe(0);

dispatchSlideEventSequence(sliderNativeElement, 0, 0.19, gestureConfig);
fixture.detectChanges();

expect(testComponent.control.value).toBe(19);
});

it('should update the value when the control is set', () => {
expect(sliderInstance.value).toBe(0);

testComponent.control.setValue(7);
fixture.detectChanges();

expect(sliderInstance.value).toBe(7);
});

it('should update the disabled state when control is disabled', () => {
expect(sliderInstance.disabled).toBe(false);

testComponent.control.disable();
fixture.detectChanges();

expect(sliderInstance.disabled).toBe(true);
});

it('should update the disabled state when the control is enabled', () => {
sliderInstance.disabled = true;

testComponent.control.enable();
fixture.detectChanges();

expect(sliderInstance.disabled).toBe(false);
});

it('should have the correct control state initially and after interaction', () => {
let sliderControl = testComponent.control;

// The control should start off valid, pristine, and untouched.
expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(true);
expect(sliderControl.touched).toBe(false);

// After changing the value, the control should become dirty (not pristine),
// but remain untouched.
dispatchClickEventSequence(sliderNativeElement, 0.5);
fixture.detectChanges();

expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(false);
expect(sliderControl.touched).toBe(false);

// If the control has been visited due to interaction, the control should remain
// dirty and now also be touched.
sliderInstance._onBlur();
fixture.detectChanges();

expect(sliderControl.valid).toBe(true);
expect(sliderControl.pristine).toBe(false);
expect(sliderControl.touched).toBe(true);
});
});

});

// Disable animations and make the slider an even 100px (+ 8px padding on either side)
// so we get nice round values in tests.
const styles = `
Expand Down

0 comments on commit c14978b

Please sign in to comment.