refactor with tests