refactor, add test and desc