Last active
December 3, 2020 08:24
-
-
Save takuya-nakayasu/5cb4cd8ea3014b39341eab18217f24aa to your computer and use it in GitHub Desktop.
サロゲートペア
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
import { Component, OnInit } from '@angular/core'; | |
/** | |
* This is unit test code for StringValidator using karma. | |
*/ | |
import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
import { | |
FormBuilder, | |
FormGroup, | |
FormsModule, | |
ReactiveFormsModule | |
} from '@angular/forms'; | |
import { StringValidator } from './string.validator'; | |
/** | |
* Component that creates input field for test | |
* | |
* @export | |
* @class RegisterComponent | |
*/ | |
@Component({ | |
selector: 'app-register', | |
template: ` | |
<form [formGroup]="form"> | |
<label>surrogatePairMinLength</label> | |
<input formControlName="surrogatePairMinLength" /> | |
<label>surrogatePairMaxLength</label> | |
<input formControlName="surrogatePairMaxLength" /> | |
</form> | |
` | |
}) | |
export class RegisterComponent implements OnInit { | |
public form: FormGroup; | |
constructor(private fb: FormBuilder) {} | |
/** | |
* initialize form | |
* | |
* @memberof RegisterComponent | |
*/ | |
public ngOnInit(): void { | |
this.form = this.fb.group({ | |
surrogatePairMinLength: [null, StringValidator.surrogatePairMinLength(5)], | |
surrogatePairMaxLength: [null, StringValidator.surrogatePairMaxLength(5)] | |
}); | |
} | |
} | |
/** | |
* Check if the method checks invalid_inputs and valid_inputs correctly | |
* | |
* @param {string} field_name | |
* @param {RegisterComponent} component | |
* @param {string[]} valid_inputs | |
* @param {string[]} invalid_inputs | |
*/ | |
function assertValues( | |
field_name: string, | |
component: RegisterComponent, | |
valid_inputs: string[], | |
invalid_inputs: string[] | |
): void { | |
const control = component.form.controls[field_name]; | |
for (const invalid of invalid_inputs) { | |
control.setValue(invalid); | |
expect(control.valid).toBeFalsy(); | |
} | |
for (const valid of valid_inputs) { | |
control.setValue(valid); | |
expect(control.valid).toBeTruthy(); | |
} | |
} | |
it('surrogatePairMinLength', () => { | |
const valid_inputs = ['12🐍4🏴', '1吉😀家😀🏴😱', '', null]; | |
const invalid_inputs = ['😀😀😀😀', '😀😀 😀', 'abce', '1234']; | |
assertValues( | |
'surrogatePairMinLength', | |
component, | |
valid_inputs, | |
invalid_inputs | |
); | |
}); | |
it('surrogatePairMaxLength', () => { | |
const valid_inputs = ['12🐍45', '1吉🏴😀', '', null]; | |
const invalid_inputs = ['😀😀😀😀😀😀', '😀😀 😀😀😀', 'abcedf', '123456']; | |
assertValues( | |
'surrogatePairMaxLength', | |
component, | |
valid_inputs, | |
invalid_inputs | |
); | |
}); | |
}); |
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
import { length } from 'stringz'; | |
import { Injectable } from '@angular/core'; | |
import { AbstractControl, FormControl, ValidatorFn } from '@angular/forms'; | |
/** | |
* Check if the value is empty | |
* | |
* @private | |
* @param {*} value | |
* @returns {boolean} | |
* @memberof NumberValidator | |
*/ | |
function isEmptyInputValue(value: any): boolean { | |
// we don't check for string here so it also works with arrays | |
return value == null || value.length === 0; | |
} | |
/** | |
* Common validator imported from Chat-co robot | |
* | |
* @export | |
* @class StringValidator | |
*/ | |
@Injectable() | |
export class StringValidator { | |
/** | |
* サロゲートペア文字(絵文字など)も含む最小文字数 | |
* | |
* @static | |
* @param {number} minLength | |
* @return {*} {ValidatorFn} | |
* @memberof StringValidator | |
*/ | |
public static surrogatePairMinLength(minLength: number): ValidatorFn { | |
return (control: AbstractControl): { [key: string]: any } => { | |
const value = (control.value || '') + ''; | |
if (value === '') { | |
return null; | |
} | |
return length(value) >= minLength | |
? null | |
: { minlength: { requiredLength: minLength } }; | |
}; | |
} | |
/** | |
* サロゲートペア文字(絵文字など)も含む最大文字数 | |
* | |
* @static | |
* @param {number} maxLength | |
* @return {*} {ValidatorFn} | |
* @memberof StringValidator | |
*/ | |
public static surrogatePairMaxLength(maxLength: number): ValidatorFn { | |
return (control: AbstractControl): { [key: string]: any } => { | |
const value = (control.value || '') + ''; | |
if (value === '') { | |
return null; | |
} | |
return length(value) <= maxLength | |
? null | |
: { maxlength: { requiredLength: maxLength } }; | |
}; | |
} | |
} |
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
import { length, substring } from 'stringz'; | |
import { | |
Directive, | |
ElementRef, | |
HostListener, | |
Input, | |
Renderer2 | |
} from '@angular/core'; | |
/** | |
* Surrogate pair max length directive. | |
* | |
* @export | |
* @class SurrogatePairMaxLengthDirective | |
*/ | |
@Directive({ | |
selector: '[appSurrogatePairMaxLength]' | |
}) | |
export class SurrogatePairMaxLengthDirective { | |
@Input() public appSurrogatePairMaxLength: number; | |
constructor(private el: ElementRef, private renderer: Renderer2) {} | |
/** | |
* Handles input event. | |
* | |
* @param {*} event | |
* @memberof SurrogatePairMaxLengthDirective | |
*/ | |
@HostListener('input', ['$event']) | |
public onChange(event: any): void { | |
if (length(event.target.value) > this.appSurrogatePairMaxLength) { | |
this.renderer.setAttribute( | |
this.el.nativeElement, | |
'value', | |
substring(event.target.value, 0, this.appSurrogatePairMaxLength) | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment