refact some
add test
modify test
refact some