add some tests and refactor