# Installation Create autoloader and pull in any libiraries for testing (PHPUnit) ``` composer install ``` Create an input file in the format discussed in `homework.txt` # Running ``` php scripts/run.php [options] ``` Available CLI options - -f - input file with the vendors data - -d - delivery day (dd/mm/yy) - -t - delivery time in 24h format (hh:mm) - -l - delivery location (postcode without spaces, e.g. NW43QB) - -c - number of people to feed Example: ``` php scripts/run.php -fdata/input.txt -c150 -lEC123 -t12:00 -d09/05/18 ``` To run unit tests: ``` php ./vendor/bin/phpunit tests ``` # Design Decisions ## Coding style and standards Where possible I have tried to implement a consistent standard of code, namely using PSR2. I've also added doc blocks to each class, function and class variable. In general I am happy to work with many different coding standards, but here I have tried to show that my focus is on a clear and consistent code style. I have added a constraint to the composer json for this test so that php7 is a hard requirement. I decided that it's useful to show that I understand the differences in major and minor versions of PHP and can therefore write relevant and runnable code that runs, regardless of the system constraints. # Structure Set-up of classes using composer and PSR4 autoloading standard. ## Input handling Usually I'd avoid doing any of this input handling manually and I would much prefer using a well supported OO library such as `symfony/console`. In this case I have created my own `App\Script\Input` class that uses PHP's `getopt` function to load the required options and do some basic exception handling when options are missing or formatted incorrectly. ## Output handling Again, I would prefer to use something like `symfony/console` here to easily produce well formatted CLI output, including progress bars etc. Here I have kept things very simple by just using `echo` to output the results from a search, keeping the format consistent with the input file. ## Storage/Persistence Here I decided against of any long-term persistence and instead I have created a `App\Model\Collection` class that acts as the storage for the input data and the filtered data that will be returned to the user. ## File Handling I have also kept this part as simple as possible. The class `App\Handler\File` simply loads a file into a string for proper parsing later. ## Model I decided to create a couple of models for `App\Model\Vendor` and `App\Model\Menu`. These items, along with the collection mean we have all the data required accessible easily from memory in a structured format. The Vendor class then handles loading instances of itself, and returning itself as a string for output. If this task was more complex I'd consider removing this content to some input/output adapters that would mean a change in the specific formats would simply require adjustments to the adapter or creation of new adapters. ## Filtering The filtering is tightly coupled with both the `App\Model\Collection` and the `App\Model\Vendor` classes. I choose to do this because the vendor and the collection have the closest access to the data that we are filtering on. If I had chosen some data persistence such as a database like MySQL, or a search engine like Elastic Search then the logic for filtering would probably be removed from the collection and perhaps placed in some form of loading/saving adapter or handlers. # Testing I have not attempted to get full coverage of the code, and I have not attempted to cover all the possible use cases for input. I have added these unit tests, using PHPUnit to show that I am capable of writing testable code and writing unit tests to cover that code. Because of time constraints I have left this part a little light. Usually I would prefer to make a base test class, or many base test classes for similar objects and have many more tests for each component. I happy to discuss more about how I would enhance these unit tests and the main project code in-order to get better test coverage.