This app tests different promotions for different flavors of chocolate. The different promotions are as follows. When a shopper trades the required number of:
milk
wrappers they will receive one complimentarymilk
chocolate and one complimentarysugar free
chocolate.white
wrappers they will receive one complimentarywhite
chocolate and one complimentarysugar free
chocolate.sugar free
wrappers they will receive one complimentarysugar free
chocolate and one complimentarydark
chocolate.dark
wrappers they will receive one complimentarydark
chocolate.
- This app was created with ruby version 2.3.1
- This application uses the built in Ruby CSV library and minitest for its testing library.
To run this project, perform the following:
cd
into the project's directory- Three rake commands have been set up to run the app
rake all
- Run all unit tests and output the redemptions filerake tests
- Run all unit testsrake redemptions
- Run runner file to generate redemptions output
- Individual test files can be ran with
ruby test/file_name.rb
- The runner file can be ran with
ruby lib/runner.rb
The app is split into four separate classes:
- OrdersReader - read the csv file and create an order object with each row
- Order- Compute promotional calculations
- Promotion - Contains current promotional rules for each flavor of chocolate
- OrdersWriter - write data to csv file with correct format
A main design goal was to isolate the flavors and promotion rules to only one location in my app to increase future flexibility. This is why I created the rules hash in the promotion model. If future orders have additional chocolate flavors with a different set of rules, I only have to update one class in my app.
A main design challenge for me was balancing single responsibility classes with simplicity. In a previous iteration I created an IncomingOrders class that iterated through each row of the csv file and created an order object. I can see this class being useful if the data in the csv file was inconsistent and needed to be standardized. For simplicity sake, I removed the class and gave that responsibility to the OrdersReader class through the csv.foreach method.
Along those same lines, I previously had an OutgoingOrder class. This class closely resembled a data class so I was able to remove it and give the responsibility to built in ruby methods. For example, in a previous iteration while writing my csv file I was calling #{outgoing_order.milk}
. I removed the OutgoingOrder class and am now iterating over an order hash and printing #{flavor}
and #{quantity}
to produce the same output.