Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactoring to extract and test more AppStore functionality #6125

Merged
merged 30 commits into from
Nov 29, 2018

Conversation

shiftkey
Copy link
Member

@shiftkey shiftkey commented Nov 7, 2018

Overview

There was a request in #6124 to decompose some complex code in AppStore._loadStatus to make it more readable, but I also wanted to take it further and see if I can get this code under test.

Rendered Markdown

Closes #6124

Description

The goal with this PR was to be able to write some meaningful tests around complex parts of AppStore, while avoiding the overhead of getting AppStore setup and in the correct state for testing.

The initial request to extract these into functions was a start, but I also wanted to achieve two things:

  • make these functions stateless, so they could be tested in isolation of AppStore
  • wrap the existing behaviour in tests, so we can understand the behaviour and catch regressions later

I settled on just covering the important code paths for both updateChangedFiles and updateConflictState and was able to hit 100% coverage with a bit of work:

The pattern that I ended up with does feel a bit like reducers in Redux, but with some caveats beyond the generic function updateSomeState<T>(prevState: T, ...args): T:

  • each function only cares about updating a subset of T, so making each function merge in previous state to then return T feels like overkill right now
  • we already have infrastructure inside RepositoryStateCache to handle merging state changes together
  • I want the tests to only focus on what's changed - so making these functions return the subset of values that need updating helps with test clarity

Things of note so far:

  • I moved the functions up to app/src/lib/stores/updates so these are close to AppStore, but avoid the churn of potential conflicts in AppStore itself
  • I created an interfaces for IStatsStore to stub and test the actions that we need to fire inside updateConflictState, and we can refine that as we need to test more things
  • setting up tests - both of these functions need IChangesState and IStatusResult to work, and those contain a lot of noise. I fell into a pattern using createState and createStatus factory functions to construct state needed for tests by taking a base object and merging it with just the fields that were relevant to the test. These helpers now live in app/test/unit/stores/updates/changes-state-helper.ts and they were a great help to keep the tests focus on the specific scenario
  • DiffSelectionType enum is now a string enum because the strings help with readability in the tests ('All' !== 'None' is much easier to understand than 0 !== 1)

TODO:

  • tidy up history after generate HTML bundle of coverage stats by default #6129 is merged now that I've settled on a reasonable pattern and code organization
  • write some docs around the new testing infrastructure for app store functions
  • gather feedback
  • address this TODO inside app/src/lib/stores/updates/changes-state.ts

// TODO: I want to use generics here so I don't need to hard-code the keys

Release notes

Notes: no-notes

@shiftkey shiftkey added the tech-debt Issues and pull requests related to addressing technical debt or improving the codebase label Nov 7, 2018
@shiftkey shiftkey force-pushed the extract-update-logic-for-testing branch 2 times, most recently from fe1d0c3 to 0e1c93f Compare November 8, 2018 16:16
@shiftkey shiftkey changed the title [WIP] experiment with extracting and testing AppStore functionality experiment with extracting and testing AppStore functionality Nov 8, 2018
@shiftkey shiftkey force-pushed the extract-update-logic-for-testing branch from 361a415 to 9071187 Compare November 13, 2018 20:41
@shiftkey shiftkey added the ready-for-review Pull Requests that are ready to be reviewed by the maintainers label Nov 14, 2018
@shiftkey shiftkey requested review from a team November 14, 2018 14:45
@shiftkey
Copy link
Member Author

shiftkey commented Nov 14, 2018

Opening this up for feedback - check out the new docs section that introduces this area.

I'm currently looking for feedback about these areas:

  • how does the pattern of extract functions and importing into AppStore feel?
  • how do the tests themselves feel? I wanted to get both functions covered 100% without writing too much tests, so hopefully it's not too confusing.
  • is there any other ideas in this vein we should explore while we're in here?

@shiftkey
Copy link
Member Author

Also, #6124 is marked for 1.5.1 but I won't pull this into the milestone until I've got some initial feedback on it.

@shiftkey shiftkey changed the title experiment with extracting and testing AppStore functionality refactoring to extract and test more AppStore functionality Nov 14, 2018
@Daniel-McCarthy
Copy link
Member

how does the pattern of extract functions and importing into AppStore feel?

I would say that from my perspective this is a quite natural progression and it makes a lot of sense to export these from this updates folder. At first this felt a bit confusing, but I think it makes sense as it should make the AppStore source file a bit cleaner by not needing quite so much defined inside it while still making use of those functions via importing.

how do the tests feel?

I'd say one benefit that I quite appreciate about this is that as functionality is branched out into their own files/folders it helps organize the relevant tests to a similar folder structure, which improves discoverability. Rather than potentially having quite as many jammed in one folder with potentially different naming schemes. (Such as may happen with the many files the base of the /lib/ folder).


I'm going to explore this a bit further later today and update if I find anything I feel is worth some discussion on that may be more useful. So far I think this is a nice direction.

@iAmWillShepherd iAmWillShepherd self-assigned this Nov 21, 2018
Copy link
Contributor

@iAmWillShepherd iAmWillShepherd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice code 🎨

docs/technical/adding-tests.md Outdated Show resolved Hide resolved
Co-Authored-By: shiftkey <brendan@github.com>
@shiftkey
Copy link
Member Author

I merged master because #6205 impacted the new tests I wrote in here

@shiftkey shiftkey added this to the 1.5.1 milestone Nov 23, 2018
@iAmWillShepherd iAmWillShepherd merged commit 6bb8a4b into master Nov 29, 2018
@iAmWillShepherd iAmWillShepherd deleted the extract-update-logic-for-testing branch November 29, 2018 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-review Pull Requests that are ready to be reviewed by the maintainers tech-debt Issues and pull requests related to addressing technical debt or improving the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants