The MobileContext and MobileFrontendHooks classes are fundamental to how MobileFrontend works but they do a lot of things, which makes them expensive to exercise and to maintain. By breaking these classes apart and testing those parts in isolation with a comprehensive suite of unit tests, we can reduce this cost and make changes with increased confidence.
Why are they expensive to exercise and maintain?
Both classes access and manipulate global state, which make them hard to isolate and, consequently, unit test. Instead, we test these classes via integration and acceptance tests, automating a UA browsing a running instance of MediaWiki, which are sluggish and, in my experience, flaky. Moreover, we don't run our entire suite of acceptance tests against each commit and I'd be willing to bet that our acceptance tests don't all of the above.
What will this cost?
I expect that the many steps of this migration will be hard to review and validate. Designing our code so that it can be unit tested will require increased discipline while making changes (and reviewing changes!). We'll have to get better at communicating and critiquing our designs. If I'm correct and there are methods of these classes that aren't covered by our acceptance tests, then there'll likely be regressions. We'll have to be disciplined in making changes small enough to balance minimising risk and maximising feedback so that we can move forward.
An often unexpected side effect of rigorously breaking apart a large object into a system of increasingly smaller objects is that, unlike a 20 line function in $yourFavouriteImperativeLanguage, it's hard to immediately see how those objects interact. High-level documentation, small interfaces, and unit tests help with this.
TODONE
- Introduce MediaWikiServices to MobileFrontend (rEMFR819064d68aba)
- Add coverage coverage to split out functions
- Replace all MobileContext::singleton() in the code base to the MobileFrontend.Context service
- Per 95629c2, MobileContext::singleton() was moved to a MobileFrontend MW service (MobileFrontend.Context), we want to break this class into small services
Nebulous thoughts that may eventually become sub-tasks (read: TODO)
- Extract:
- the MobileFrontendRequest object
- Discuss action/controller terminology with the team (@Jhernandez)
…