forked from NationalBankBelgium/stark
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stark-ui): add directive for transforming input value before pas…
…sing it to a ngControl - added directive `[starkTransformInput]` - created new module - added demo page - small refactor demo page keyboard-directives - added tests for directive ISSUES CLOSED: NationalBankBelgium#1099
- Loading branch information
1 parent
1f75d0d
commit 4a7d754
Showing
20 changed files
with
687 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./transform-input-directive/directives"; | ||
export * from "./transform-input-directive/transform-input-directive.module"; |
1 change: 1 addition & 0 deletions
1
packages/stark-ui/src/modules/transform-input-directive/directives.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./directives/transform-input.directive"; |
285 changes: 285 additions & 0 deletions
285
...ark-ui/src/modules/transform-input-directive/directives/transform-input.directive.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
/*tslint:disable:completed-docs no-identical-functions no-duplicate-string no-big-function*/ | ||
import { Component } from "@angular/core"; | ||
import { ComponentFixture, TestBed } from "@angular/core/testing"; | ||
import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms"; | ||
import { StarkInputTransformationType, StarkTransformInputDirective } from "./transform-input.directive"; | ||
import { Observer } from "rxjs"; | ||
|
||
/** | ||
* Mocks an InputEvent on the element with the given value. | ||
* @param value - the value to set the element to. | ||
* @param element - the HTMLInputElement to mock the event on | ||
*/ | ||
const mockInputEvent: (value: string, element: HTMLInputElement) => void = (value: string, element: HTMLInputElement): void => { | ||
const inputEvent: Event = document.createEvent("Event"); | ||
inputEvent.initEvent("input", true, true); | ||
|
||
element.value = value; | ||
element.dispatchEvent(inputEvent); | ||
}; | ||
|
||
describe("TransformInputDirective", () => { | ||
describe("with ngModel", () => { | ||
@Component({ | ||
selector: "test-component", | ||
template: "<input [(ngModel)]='value' [starkTransformInput]='starkTransformInputValue'/>" | ||
}) | ||
class TestComponent { | ||
public starkTransformInputValue: StarkInputTransformationType = () => { | ||
/*noop*/ | ||
}; | ||
public value: string = ""; | ||
} | ||
|
||
let fixture: ComponentFixture<TestComponent>; | ||
let component: TestComponent; | ||
let htmlInputElement: HTMLInputElement; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [StarkTransformInputDirective, TestComponent], | ||
imports: [FormsModule] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestComponent); | ||
component = fixture.componentInstance; | ||
htmlInputElement = fixture.nativeElement.querySelector("input"); | ||
|
||
// trigger initial data binding | ||
fixture.detectChanges(); | ||
|
||
expect(component.value).toBe("", "field 'value' should start as empty string "); | ||
}); | ||
|
||
it("should set value to uppercase", () => { | ||
const input: string = "upper"; | ||
const expected: string = "UPPER"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "uppercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.value).toBe(expected); | ||
}); | ||
|
||
it("should set value to lowercase", () => { | ||
const input: string = "LOWER"; | ||
const expected: string = "lower"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "lowercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.value).toBe(expected); | ||
}); | ||
|
||
it("should replace dirty word", () => { | ||
const input: string = "fudge you!"; | ||
const expected: string = "***** you!"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = (v: string) => | ||
v.replace("fudge", (match: string) => | ||
match | ||
.split("") | ||
.map(() => "*") | ||
.join("") | ||
); | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.value).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe("with formControl", () => { | ||
@Component({ | ||
selector: "test-component", | ||
template: "<input [formControl]='formControl' [starkTransformInput]='starkTransformInputValue'/>" | ||
}) | ||
class TestComponent { | ||
public starkTransformInputValue: StarkInputTransformationType = () => { | ||
/*noop*/ | ||
}; | ||
public formControl: FormControl = new FormControl(""); | ||
|
||
public constructor() { | ||
this.formControl.valueChanges.subscribe(this.changeObserver); | ||
} | ||
|
||
public changeObserver(): void { | ||
/*Placeholder for spy*/ | ||
} | ||
} | ||
|
||
let fixture: ComponentFixture<TestComponent>; | ||
let component: TestComponent; | ||
let mockValueChangeObserver: jasmine.SpyObj<Observer<any>>; | ||
let htmlInputElement: HTMLInputElement; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [StarkTransformInputDirective, TestComponent], | ||
imports: [ReactiveFormsModule] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestComponent); | ||
component = fixture.componentInstance; | ||
htmlInputElement = fixture.nativeElement.querySelector("input"); | ||
|
||
// Register mock subscription | ||
mockValueChangeObserver = jasmine.createSpyObj<Observer<any>>("observerSpy", ["next", "error", "complete"]); | ||
component.formControl.valueChanges.subscribe(mockValueChangeObserver); | ||
|
||
// trigger initial data binding | ||
fixture.detectChanges(); | ||
|
||
expect(component.formControl.value).toBe("", "field 'value' should start as empty string "); | ||
}); | ||
|
||
it("should set value to uppercase", () => { | ||
const input: string = "upper"; | ||
const expected: string = "UPPER"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "uppercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.formControl.value).toBe(expected); | ||
expect(mockValueChangeObserver.next).toHaveBeenCalledTimes(1); | ||
expect(mockValueChangeObserver.error).not.toHaveBeenCalled(); | ||
expect(mockValueChangeObserver.complete).not.toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should set value to lowercase", () => { | ||
const input: string = "LOWER"; | ||
const expected: string = "lower"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "lowercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.formControl.value).toBe(expected); | ||
expect(mockValueChangeObserver.next).toHaveBeenCalledTimes(1); | ||
expect(mockValueChangeObserver.error).not.toHaveBeenCalled(); | ||
expect(mockValueChangeObserver.complete).not.toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should replace dirty word", () => { | ||
const input: string = "fudge you!"; | ||
const expected: string = "***** you!"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = (v: string) => | ||
v.replace("fudge", (match: string) => | ||
match | ||
.split("") | ||
.map(() => "*") | ||
.join("") | ||
); | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(component.formControl.value).toBe(expected); | ||
expect(mockValueChangeObserver.next).toHaveBeenCalledTimes(1); | ||
expect(mockValueChangeObserver.error).not.toHaveBeenCalled(); | ||
expect(mockValueChangeObserver.complete).not.toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
|
||
describe("without ngControl", () => { | ||
@Component({ | ||
selector: "test-component", | ||
template: "<input [starkTransformInput]='starkTransformInputValue'/>" | ||
}) | ||
class TestComponent { | ||
public starkTransformInputValue: StarkInputTransformationType = () => { | ||
/*noop*/ | ||
}; | ||
} | ||
|
||
let fixture: ComponentFixture<TestComponent>; | ||
let component: TestComponent; | ||
let htmlInputElement: HTMLInputElement; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [StarkTransformInputDirective, TestComponent] | ||
}); | ||
|
||
fixture = TestBed.createComponent(TestComponent); | ||
component = fixture.componentInstance; | ||
htmlInputElement = fixture.nativeElement.querySelector("input"); | ||
htmlInputElement.value = ""; | ||
|
||
// trigger initial data binding | ||
fixture.detectChanges(); | ||
|
||
expect(htmlInputElement.value).toBe("", "field 'value' should start as empty string "); | ||
}); | ||
|
||
it("should set value to uppercase", () => { | ||
const input: string = "upper"; | ||
const expected: string = "UPPER"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "uppercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(htmlInputElement.value).toBe(expected); | ||
}); | ||
|
||
it("should set value to lowercase", () => { | ||
const input: string = "LOWER"; | ||
const expected: string = "lower"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = "lowercase"; | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(htmlInputElement.value).toBe(expected); | ||
}); | ||
|
||
it("should replace dirty word", () => { | ||
const input: string = "fudge you!"; | ||
const expected: string = "***** you!"; | ||
|
||
// Set directive to correct implementation | ||
component.starkTransformInputValue = (v: string) => | ||
v.replace("fudge", (match: string) => | ||
match | ||
.split("") | ||
.map(() => "*") | ||
.join("") | ||
); | ||
fixture.detectChanges(); | ||
|
||
mockInputEvent(input, htmlInputElement); | ||
fixture.detectChanges(); | ||
|
||
expect(htmlInputElement.value).toBe(expected); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.