refactor and add many testcases