solnic/virtus — pull request #190 by solnic (2013-09-16 16:23:19+00:00)
Title: [WIP] axiom types integration

This is a **WIP**

## Summary

* Almost entire Attribute sub-class hierarchy is gone. Only Boolean, Hash and EV are left + Collection is used for both Array, Set and any Enumerable-like objects
* Attribute no longer needs a name. The only required argument is *type* which can be an axiom type or a model class for EV
* Accessor/Writer/Reader are gone. This turned out to be a mistake and bad design that turned Attribute into an anaemic class and introduced a lot of complexity to solve something relatively simple
* Customized attribute behaviour is now achieved via module extensions:
* `Attribute::Named` - adds behaviour for attributes that have a name, such attributes can be used to write/read ivars in models
* `Attribute::Coercible` - coerces input before setting
* `Attribute::LazyDefault` - loads default value when reading an attribute for the first time (original default virtus behaviour in 0.5.x)
* Attribute instances are now frozen after they are finalized (not using adamantium though because initialisation is a multi-step process now)
* ALL unit specs were nuked and I've started rewriting them - I know this is a totally hard-core choice but I felt overwhelmed by the previous test suite and didn't want to dig through it while working on this integration/refactor. Instead I nuked everything and started TDDing everything I decided to change.

## Higher-level benefits coming from this integration/refactor:

* Virtus interface is dead simple and it's now easier than ever to build attributes that are used for coercions (some gems started using virtus like that so this should be helpful)
* Virtus code base is much smaller (I suspect at the end we'll have ~1.5-2k lines of code less overall)
* Thanks to axiom types it will be possible to add more additional meta-info to attributes w/o complicating virtus itself
* Test suite is simpler as only the public part of the API is being tested, internals are tested implicitly. Mutant won't have any problems with that

## Things we need to change/improve in axiom-types:

- [ ] currently it's not possible to build Hash and Collection types with member/key/value types being arbitrary classes as axiom-types assumes you will use primitives for that so it can build types from that. When you pass in some class, like OpenStruct it blows up trying to finalize it.

## TODO

- [ ] add missing specs, since I nuked all unit tests and TDDed only the parts that were changed + made changes needed to make all integration test pass I'm left with some uncovered parts (I mean on the unit level). I will fully mut-cover everything so eventually it's gonna be rock solid. I will also make sure all of the known bugs are fixed but that will probably happen in the master branch as I don't want to keep this PR for too long).
- [ ] figure out how to get rid of `TypeLookup`
- [ ] figure out how to get rid of `Attribute.primitive`
- [ ] add missing docs
- [ ] fix stuff reported by rubocop
- [ ] make sure reek/flay/flog are passing
- [ ] update README