Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Tuesday, March 22, 2016

Interesting Talk: "Code Smells: Your Refactoring Cheat Codes"

I've just watched this great talk by John Pignata: Here is the code of the example shown during the talk.

Kata: Open-Closed Principle in Ruby

Last week some friends from Software Craftsmanship Gran Canaria and I practiced doing Matteo Vaccari's Open-Closed Principle kata.

Jose M. Deniz Suarez and I paired to solve it using Ruby.

We got two versions of the code.

These are the tests:

and the code of the first version:

In this first version, we used a reduce over a list of translators. Each translator might add or not a translation of the given number to the resulting string.

To try something different from what we've tried other times, we used a template method pattern to remove the duplication between the tranlators.

Even though, we reduced the duplication, we didn't like the solution because the resulting Translator interface (public methods) had parameters that were not used by some of its derived classes.

Next, we deleted the code and try another approach. This time we used the decorator pattern.

The tests were the same except for the sayer factory method:

and this the resulting code:

Then we refactored it to remove some duplication and added a new translation whose condition didn't have to do with being multiple of some number.

This forcer us to generalize the translators passing them a predicate and a translation string through their constructors.

These are the resulting tests (only showing the new test and the sayer factory):

and code:

https://gist.github.com/trikitrok/619ecabe5ff9f8b08dac

It was a lot of fun.

The constrainsts of this kata are very interesting to practice refactoring and understand the OCP principle.

You can find the code in this GitHub repository.

I'd like to thank Matteo Vaccari for creating it and the great people of Software Craftsmanship Gran Canaria for the fun and the interesting discussions about the different solutions we got.

PS: The "bokata de pata" was also great :)

Tuesday, January 26, 2016

Sunday, September 20, 2015

Kata: Yatzi refactoring kata in Ruby

Last night I did the Yatzy refactoring kata in Ruby.

I mainly used it to practice with Enumerable functions.

This is the original code:

and this is the refactored one:

I committed after every small refactoring (the commits step by step).

You can find the code in this repository in GitHub.

Wednesday, August 5, 2015

Contract tests for interfaces discovered through TDD

We were working through the following iterations of an exercise:

First iteration
A user can register with a user name.

For instance: @foolano

If anyone else has already registered with that name there is an error.

Second iteration
A user can follow another users.

To do so it's only required to know the user name of the user to be followed.

Anyone can query the followers of any given user just knowing its user name.

Third iteration
The registered users and their followers must be persisted.
(source: Diseño modular dirigido por pruebas workshop at PyConEs 2014)

We produced several application services for this features that at some point collaborated with a users repository that we hadn't yet created so we mocked it in their specs.

In these tests, every time we allow or expect a method call on our repository double, we are defining not only the messages that the users repository can respond to (its public interface) but also what its clients expect from each of those messages, i.e. its contract.

In other words, at the same time we were testing the application services, we defined from the point of view of its clients the responsibilities that the users repository should be accountable for.

The users repository is at the boundary of our domain.

It's a port that allows us to not have to know anything about how users are stored, found, etc. This way we are able to just focus on what its clients want it to do for them, i.e., its responsibilities.

This results in more stable interfaces. As I heard Sandi Metz say once:

"You can trade the unpredictability of what others do for the constancy of what you want."

which is a very nice way to explain the "Program to an interface, not an implementation" design principle.

How those responsibilities are carried out is something that each different implementation (or adapter) of the users repository must be responsible of.

However, the terms of the contract that its clients rely on, must be respected by all of the adapters.

In this sense, any adapter must be substitutable by any other without the clients being affected, (yes, you're right, it's the Liskov substitution principle).

The only way to ensure this substitutability is by testing each new adapter to see if it also respects the terms of the contract.

This is related to J. B. Rainsberger's idea of contract tests mentioned in his Integrated Tests Are A Scam talk and in his great TDD course, and also to Jason Gorman's idea of polymorphic testing.

Ok, but how can we test that all the possible implementations of the user repository respect the contract without repeating a bunch of tests?

This is one way to do it in Ruby using RSpec.

We created a RSpec shared example in a file named users_repository_contract.rb where we wrote the tests that characterize the behavior that users repository clients were relying on:

Then for each implementation of the users repository you just need to include the contract using RSpec it_behaves_like method, as shown in the following two implementations:

You could still add any other test that only had to do with a given implementation in its spec.

This solution is both very readable and reduces a lot of duplication in the tests.

However, the idea of contract tests is not only important from the point of view of testing.

In dynamic languages, such as Ruby, they also serve as a mean to highlight and document the role of duck types that might otherwise go unnoticed.

Wednesday, July 22, 2015

Kata: Binary Search Tree in Ruby

Yesterday in the Barcelona Software Craftsmanship coding dojo we did the Binary Search Tree kata.

Raúl Lorca and I paired using TDD in C# to get to a pretty OO solution.

We didn't finish the exercise. We got to create the binary search tree but we didn't have time to code the in-order depth-first traversal.

Well, it doesn't matter. The important thing is that we practiced TDD, recursion and OO by test-driving a recursive data structure.

Today, with a bit more of time, I did the the whole kata in Ruby.

These are the resulting tests, after deleting some I used as scaffolding to get to the final version of the code (check the commits if you want to see the evolution of the tests):

And this is the final version of the code:

To document the whole TDD process I committed the code after every passing test and every refactoring.

You can check the commits step by step here and all the code in this repository in GitHub.

I had done the same exercise in Clojure several weeks ago as part of the Exercism problems. Compare the code there with this one if you like.