refractor the code and test code, all test cases are ok!