อาทิตย์ที่แล้ว ผมได้มีโอกาสเข้าไปดู source code ของ moment.js library เลยเจอกับ code บางส่วนที่ช่วยเพิ่มความยืดหยุ่นในการเขียน program เพื่อรองรับการทำงานแบบ dynamic ด้วยวิธีดังต่อไปนี้
โดยในตัวอย่างนี้ผมจะใช้ code ตัวอย่างด้วยภาษา TypeScript ที่เป็นภาษา super set ของ JavaScript หมายความว่า
โดยเราจะเริ่มตัวอย่างนี้ด้วยการสร้าง User class
User.ts
//ES6 export default to a User class
export default class User {
private _firstName: string;
private _lastName: string;
//property and method are public by default
get firstName(): string {
return this._firstName;
}
set firstName(value: string) {
this._firstName = value;
}
get lastName(): string {
return this._lastName;
}
set lastName(value: string) {
this._lastName = value;
}
getFullName(): string {
return `${this._firstName} ${this._lastName}`
}
saySomething(message: string, time: number): string[] {
var totalMessages: string[] = [];
for (let index = 0; index < time; index++) {
totalMessages.push(message);
}
return totalMessages;
}
}
สำหรับ code ตัวอย่างทดสอบการใช้งาน class User ผมขอยกตัวอย่างในรูปแบบของ unit test โดยใช้ test framework ที่ชื่่อ Jasmine โดยผู้อ่านสามารถศึกษาเพิ่มเติมได้จาก
การใช้งาน property และ method แบบปกติ
ตัวอย่างใช้งาน property และ method ของ User object แบบปกติ
UserSpect.ts
describe('with normal style', () => {
it('should return a correct full name', () => {
//given
let user = new User();
user.firstName = 'Anthony';
user.lastName = 'CodeSanook';
//when
let fullName = user.getFullName();
//then
expect(fullName).toBe('Anthony CodeSanook');
});
});
describe('with dynamic style', () => {
it('should return a correct full name', () => {
//given
let user = new User();
user['firstName'] = 'Anthony';
user['lastName'] = 'CodeSanook';
//when
let fullName = user['getFullName']();
//then
expect(fullName).toBe('Anthony CodeSanook');
});
});//end describe
ต่อไปเราจะทดสอบการเรียกใช้งาน JavaScript property method name ด้วยการเรียกชื่อผ่าน string key
describe('with dynamic style', () => {
it('should return a correct full name', () => {
//given
let user = new User();
user['firstName'] = 'Anthony';
user['lastName'] = 'CodeSanook';
//when
let fullName = user['getFullName']();
//then
expect(fullName).toBe('Anthony CodeSanook');
});
});//end describe
หรือ iterate all member names
it('should return all members', () => {
//given
let user = new User();
let userKeys: string[] = [];
//when
for (let key in user) {
userKeys.push(key);
}
//then
expect(userKeys).toEqual(jasmine.arrayContaining(
[
'firstName',
'lastName',
'getFullName',
'saySomething'
]));
});
การใช้งาน apply และ call function
สอง function นี้ความต่างกันที่ apply เราส่ง arguments เป็น array (a in apply == array) และ call เราส่ง argument เป็น comma separated values (c in call == comma)
ตัวใช้งาน apply function
describe('with apply function ', () => {
it('should return a correct full name', () => {
//given
let userA = new User();
let userB = new User();
userB['firstName'] = 'Anthony';
userB['lastName'] = 'CodeSanook';
//when
//use apply we pass arguments as array
let fullName = userA.getFullName.apply(userB);
//then
expect(fullName).toBe('Anthony CodeSanook');
});
it('should return correct total message count', () => {
//given
let userA = new User();
let userB = new User();
userB['firstName'] = 'Anthony';
userB['lastName'] = 'CodeSanook';
//when
//use apply we pass arguments as array
let messages = userA.saySomething.apply(userB, ['Hello World with apply', 5]);
//then
expect(messages.length).toBe(5);
});
});//end describe
ตัวอย่างใช้งาน call function
describe('with call function', () => {
it('should return a correct full name', () => {
//given
let userA = new User();
let userB = new User();
userB['firstName'] = 'Anthony';
userB['lastName'] = 'CodeSanook';
//when
//use apply we pass arguments as array
let fullName = userA.getFullName.call(userB);
//then
expect(fullName).toBe('Anthony CodeSanook');
});
it('should return correct total message count', () => {
//given
let userA = new User();
let userB = new User();
userB['firstName'] = 'Anthony';
userB['lastName'] = 'CodeSanook';
//when
//use apply we pass arguments as comma separated values
let messages = userA.saySomething.call(userB, 'Hello World with call', 10);
//then
expect(messages.length).toBe(10);
});
});//end describe
ตัวอย่าง output ของ code ที่เราเขียนกัน
download source code ตัวอย่างได้จาก git hub เลยครับ
https://github.com/aaronamm/CodeSanook.Examples
ขั้นตอนการ setup project ในตัวอย่างนี้