refactor and add tests
refactor