Work through the story you are given, making the refactors that are needed to get the story done. In the case of 'Chore' stories, the refactoring expectation is given. In other stories, you will have to judge on your own whether you are boiling the ocean, or skimping on code change. There isn't a right answer, but there may be wrong answers.
Along the way we are going to find ways to measure the cost of each story and each commit. Basic costing is going to be estimated by some metrics encompassed in gems. The metrics are going to fail us in the fuzzy sense, and so we need to supplement with some intuition. For example, we will have metrics that show test coverage, but they don't analyze the cost and style of those tests. We are going to need to think through most things on our own.
The application itself is written in pure Ruby, no gem knowledge required.
It is run by calling an executable file located at the project's root
like this: ./task-it-to-me.
It is a command line task management app.
There is 100% test coverage. That can be confirmed via rake coverage. It
generates a report in /coverage.
Tests are in rspec and are dead simple to follow. The only helper function
helps strip out the color markup from the output so it is easier to make
assertions against.
To be testable the command line app dependency injects stdin and stdout. In
the executable, the Ruby globals $stdin and $stdout are passed in. In tests
StringIO
is passed for each of those.
Stubbing of the user input is on the stdin in tests. We can inspect the
string of the stdout in order to make assertions on what is printed out.
- Bug - unexpected app quit when editing without projects
- Bug - commands fail if command has a space afterwards
- Chore - follow the color
- Chore - follow the shape
- Feature - show recently finished tasks
- Feature - custom colors with configuration
- Feature - multiple users
- Feature - super efficient commands
Refactoring on a project is complex since it operates in two axis:
- How to unwind complex and often undocumented code? This is technical (and a bit archeological).
- How much to do? This should be guided by economics/value. How easy is the code to change and which parts need to change?
While it can be tempting to want to implement a whole new architecture on any project you start. Messes are just fine for the project if they never need to change.
After gather or working enough in a project to feel like you can jump in, refactoring should be guided by bugs and features. Things that need to change and change often should be easy to understand and change. Whereas, code that was written once but has no bugs or feature related to it can stay a terrible mess.
Refactoring isn't about creating perfection. It is about keeping a project maintainable.
Each story will come with it's own instructions. At the bottom there will be a way to submit your solution.
Make small PRs so you can get real feedback.
You have full test coverage!
The goal is to keep tests passing with each change. Katrina Owens, a master refactorer has a rule: you should be one undo away from green tests at any moment. When refactoring, it can be tempting to rip up the world and have it come back together at some point in the future. That is a bad plan. So, in this exercise, stay green. Integrate small changes quickly, and undo them when they don't work as expected. Then take an even smaller step.
Since all the tests are passing, and we have 100% coverage, any bug is a failure in the tests. Here are steps for tackling a bug:
- Investigate:
- Look around
- Come up with a theory
- Find a way to test the theory
- Take notes
- Loop until confident of source of the problem
- Rollback any code changes
- Write a failing test
- Make the test pass
Since features are new behavior, you are responsible for writing both tests and code. Write the tests first. Putting aside any TDD related hype, the process will help you focus onthe interfaces of objects and how they communicate, rather than the details of implementation. Then write the code.