refactor and add more test cases