Saturday, May 28, 2005

TiddlyWiki

Wiki that written in HTML, CSS and JavaScript.
No any Serverside Logic.
Link

Related link from Roti

Friday, May 27, 2005

Sitemesh unsupported encoding

วันนี้แวะไปบริษัทฯ ได้รับแจ้งว่าตัว tapestry มีปัญหา
กับ sitemesh โดยเกิด exception ที่ตัว
sitemesh ที่ Class TextEncoder
มีข้อความว่า "Unsupported encoding Windows-874"

ก็เลยต้องใล่ดู source code ของ Sitemesh
พบว่าตัว Class TextEncoder ใช้
class java.nio.charset.Charset ในการ check encoding
ซึ่งการเรียก Charset.isSupport("Windows-874")
จะได้ผลลัพท์เป็น false

ก็เลยพยายามนั่งหาว่า
ใครเป็นคนทำให้เกิด charset Windows-874 ขึ้นมา
ทดลอง -Dfile.encoding=TIS-620 ก็แล้ว
ทดลองใส่ <meta-equiv="content-type" content="text/html;charset=TIS-620" />
ก็ยังเป็นอยู่

จากนั้นก็ลองไปทดสอบบน linux server
พบว่าเจ้า Windows-874 ยังตามมาหลอกหลอน
ก็เลยรู้ว่าเป็นปัญหาที่ตัว Tapestry ยังแน่นอน
จากการไล่ดู พบว่าที่ Application config file มีการใส่ว่า
<property name="org.apache.tapestry.output-encoding">Windows-874</property>

ก็เลยจัดการเปลี่ยนเป็น
<property name="org.apache.tapestry.output-encoding">tis-620</property>


ส่วนประเด็นว่าใครเป็นคนใส่เข้ามา
ก็พบว่าตัวเองนี่แหล่ะเคยเขียน App ไว้ App หนึ่ง
ที่ config ไว้แบบนี้
สมัยนั้นไม่ได้ใช้ sitemesh ก็เลยไม่เกิดปัญหาอะไร
พอมาเริ่มโปรเจคใหม่ น้องๆเขาก็เล่น copy
มาทั้งดุ้น ก็เลยเกิดปัญหาขึ้น

จากการใล่ทดสอบดูพบประเด็นเพิ่มเติมดังนี้
  • ถ้าเราใช้ jdk1.5 คำสั่ง Charset.isSupport("Windows-874")
    จะได้ผลลัพท์เป็น True
    ส่วน jdk1.4 ได้ผลลัพท์เป็น false
  • กรณีที่เราไม่ได้ระบุค่า org.apache.tapestry.output-encoding
    ค่า default ของ Tapestry ก็คือ utf-8
  • ใน tapestry ถ้าเราใช้ component shell
    ตัว tapestry จะ generate meta-equiv="content-type"
    ให้เราโดยอัติโนมัติ

Related link from Roti

Monday, May 23, 2005

On-the-fly Sparklines with JavaScript and XBM

คงจำ SparkLine ที่เคยพูดถึงกันได้นะครับ
วันนี้เจอ javascript library ที่ใช้ generate
spark line ที่ฝั่ง browser ได้เลย
Link

Note: เท่าที่ลองดู ดูได้แต่ใน firefox
แต่ยังไม่ work ใน safari, opera 6, ie

Related link from Roti

Processing

สิบปากว่าไม่เท่าตาเห็น ลองดูที่นี่ครับ
Substrate
อย่าลืมลอง lunch applet หล่ะครับ

จากนั้นก็ลองเล่นหมากรุกที่นี่ดูครับ
Thinking Machine4

ตัวที่เป็นหัวใจก็คือ Processing
Processing is a programming language and environment built for the media arts and design communities. It is created to teach fundamentals of computer programming within a visual context and to serve as a software sketchbook. It is used by students, artists, designers, architects, and researchers for learning, prototyping, and production.

Related link from Roti

Sunday, May 22, 2005

jMock

ใน Application ที่ AppFuse generate มาให้นั้น
มีตัวอย่างการ test service layer โดยใช้ Mock Object ด้วย
โดยตัว Tool ที่ทาง AppFuse เลือกใช้ ก็คือ jMock

หลักการก็คือ สมมติว่าเรามี Service ที่ชื่อ AuthenticateService อยู่
class AuthenticateService {
private UserDao userDao;

public boolean isAuthenticate(String userId, String passwd) {
User user = userDao.getUser(userId);
if (user != null && user.getPassword().equals(passwd)) {
return true;
}
return false;
}

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}


ตัว AuthenticateService เรียกใช้ UserDao
โดย UserDao จะค้นหา user จาก persistent layer ให้
interface UserDao {
public User getUser(String userId);
}


ในการ test กรณีที่เราต้องการ test unit เฉพาะ
AuthenticateService ว่า logic ทำงานถูกต้องหรือไม่
โดยไม่ต้องการลากเอา Persistent Layer หรือ Dao มา test ด้วย
ก็ทำได้โดยใช้ Mock Object เข้ามาช่วย

เริ่มโดยการเขียน TestCase ที่ extends MockObjectTestCase
public class AuthenticateServiceTest extends MockObjectTestCase {
public void testAuthenticate() {

}
}


จากนั้นใน test method เราก็จะทำการ setup Mock Object ก่อน

Mock userDaoMock = new Mock(UserDao.class);
AuthenticateService svr = new AuthenticateService();
svr.setuserDao(userDaoMock.proxy());


ก่อน test เราก็ setup ค่าที่เราคาดหวังไว้ให้
mock ตอบกลับออกมาเมื่อมีการเรียกใช้
method getUser

User userData = new User();
userData.setUserId("tomcat");
userData.setPassword("testIt");

userDaoMock.expects(once()).method("getuser")
.with(eq("tomcat")).will(returnValue(userData));


จากนั้นก็เป็นเริ่ม test
โดย assert ผลลัพท์ที่ได้จากการ call isAuthenticate

boolean result = svr.isAuthenticate("tomcat", "testIt");
assertTrue(result);
result = svr.isAuthenticate("tomcat", "blabla");
assertFalse(result);
userDaoMock.verify();


หลายคนที่เคย test ระบบที่มี dependency
อีรุงตุนังไปหมดนั้นคงรู้ว่ามันยากต่อการ run test ขนาดไหน
แต่จะเห็นได้ว่าการใช้ mock เข้ามาช่วยนั้น
จะทำให้เราสามารถ Isolate การ test ออกเป็นส่วนย่อยๆได้
ซึ่งทำให้ง่ายต่อการ test และ test ซ้ำได้ง่ายขึ้น

Related link from Roti