README.md in prezzo-0.1.0 vs README.md in prezzo-0.2.0

- old
+ new

@@ -1,6 +1,6 @@ -# Prezzo +# Prezzo [![Build Status](https://travis-ci.org/marceloboeira/prezzo.svg?branch=master)](https://travis-ci.org/marceloboeira/prezzo) > Toolbox to create complex pricing models ## Installation Add this line to your application's Gemfile: @@ -9,39 +9,160 @@ gem "prezzo" ``` And then execute: - $ bundle +``` +$ bundle +``` Or install it yourself as: - $ gem install prezzo +``` +$ gem install prezzo +``` ## Usage -### Basic: +### Prezzo::Context + +The `Prezzo::Context` is a source of data for your calculators. Basically, it receives a hash of params and it validates its content, in order to make the calculations safe. + +e.g.: + ```ruby +module Uber + class Context + include Prezzo::Context + CATEGORIES = ["UberX", "UberXL", "UberBlack"].freeze + + validations do + required(:category).filled(included_in?: CATEGORIES) + required(:distance).filled(:float?) + required(:total_cars).filled(:int?) + required(:available_cars).filled(:int?) + end + end +end + +context = Uber::Context.new(category: "UberBlack", ...) + +# when valid +context.valid? +#=> true + +# when invalid +context.valid? +#=> false + +context.errors +# { distance: ["must be a float"]} +``` + +### Prezzo::Calculator + +The `Prezzo::Calculator` is a simple interface for injecting dependencies on your calculators and calculating the price. Basically, it makes it possible to receive the context, an Hash of parameters containing the necessary information to calculate your price or a Prezzo::Context. + +e.g.: + +```ruby require "prezzo" -class MyCalculator < Prezzo::Calculator - def calculate - context.fetch(:foo) * 2 +module Uber + class PricePerDistanceCalculator + include Prezzo::Calculator + + def calculate + price_per_kilometer * distance + end + + def price_per_kilometer + 1.30 + end + + def distance + context.fetch(:distance) + end end end -MyCalculator.new(foo: 10).calculate +context = Uber::Context.new(distance: 10.0) +Uber::PricePerDistanceCalculator.new(context).calculate #=> 20.0 ``` -Check the [Uber pricing](/spec/integration/uber_pricing_spec.rb) for more complete example with many calculators and factors. +**Context Validation** +If you initialize the context with a hash, it will skip the validation, however, any object that responds to `.valid?` will attempt a validation, and it will fail if valid? returns false. + +### Prezzo::Composed + +The `Prezzo::Composed` module is an abstraction that provides a nice way of injecting other calculators define how the price will be composed with all of those calculators. + +e.g.: + +```ruby +require "prezzo" + +module Uber + class RidePriceCalculator + include Prezzo::Calculator + include Prezzo::Composed + + composed_by base_fare: BaseFareCalculator, + price_per_distance: PricePerDistanceCalculator, + + def calculate + base_fare + price_per_distance + end + end +end + +context = Uber::Context.new(distance: 10.0) +Uber::RidePriceCalculator.new(context).calculate +#=> 47.3 +``` + +### Prezzo::Explainable + +The `Prezzo::Explainable` module is an abstraction that provides a nice way of representing how the price was composed. + +e.g.: + +```ruby +require "prezzo" + +module Uber + class RidePriceCalculator + include Prezzo::Calculator + include Prezzo::Composed + include Prezzo::Explainable + + composed_by base_fare: BaseFareCalculator, + price_per_distance: PricePerDistanceCalculator, + explain_with :base_fare, :price_per_distance + + def calculate + base_fare + price_per_distance + end + end +end + +context = Uber::Context.new(distance: 10.0) +Uber::RidePriceCalculator.new(context).explain +#=> { base_fare: 4.3, price_per_distance: 21.3 } +``` + +Check the full [Uber pricing](/spec/integration/uber_pricing_spec.rb) for more complete example with many calculators and factors. + ## Development -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. +After checking out the repo, run `make` to install dependencies. Then, run `make spec` to run the tests. You can also run `make console` for an interactive prompt that will allow you to experiment. -To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). +To install this gem onto your local machine, run `make install`. To release a new version, update the version number in `version.rb`, and then run `make release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). ## Contributing -Bug reports and pull requests are welcome on GitHub at https://github.com/marceloboeira/prezzo. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. +Please consider reading out [Contributing Guide](CONTRIBUTING.md). + +This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.