thoughtworks/pacto — pull request #112 by maxlinc (2014-04-18 19:51:00+00:00)
Title: (Big) refactor - use Hashie

I started with a really small refactor. I was going to replace hash_deep_merge with hashie, which has deep_merge support as well, but also other features I wanted to use in the future.

But apparently we weren't even using deep_merge anymore, so I just went ahead with big refactor to try Hashie. The big change was turning Contract, RequestClause, and ResponseClause into a [Hashie::Dash](https://github.com/intridea/hashie#dash). This makes me feel a bit better about those classes:

> Dash is an extended Hash that has a discrete set of defined properties and only those properties may be set on the hash. Additionally, you can set defaults for each property. You can also flag a property as required. Required properties will raise an exception if unset.

Those checks (about required properties, property types, and not allowing non-existing properties) previously only existed in json-schema. So if you were loading a contract from a file you were okay, but if you were generating a contract from a real request/response or converting from another format (like apiary), then Pacto wouldn't catch mistakes.

The changes also included:
- coercion (the request and response objects are coerced to RequestClause and ResponseClause)
- deprecation notices (I want to rename body -> schema in the contract; this could probably be improved)

These three things (easily addition of properties, type coercion, and deprecation notices) should make it a lot easier for me to work on things I wanted that would require contract changes, like https://github.com/thoughtworks/pacto/issues/96, https://github.com/thoughtworks/pacto/issues/100. In fact, my changes already fix https://github.com/thoughtworks/pacto/issues/84 internally, I just need to update the contract schema to allow a host, and put a deprecation notice that it'll be required in the future.

Check it out and see what looks hacky. I think the hacks are mostly related to data normalization, and might be solvable with two PRs to Hashie:
- Don't coerce if the type already matches (see [request_clause.rb#L35-L43](https://github.com/thoughtworks/pacto/blob/hashie/lib/pacto/request_clause.rb#L35-L43))
- Allow coerce_key to use a proc, or some other way I can normalize a symbol ([request_clause.rb#L13](https://github.com/thoughtworks/pacto/blob/hashie/lib/pacto/request_clause.rb#L13)).