refactor & add tests