add more tests and refactor