Refactor RotaryEncoder and add tests