summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md56
-rw-r--r--src/Script/Input.php36
2 files changed, 60 insertions, 32 deletions
diff --git a/README.md b/README.md
index 70dd44e..c1da941 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,61 @@
# 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
+
# 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.
diff --git a/src/Script/Input.php b/src/Script/Input.php
index 6a91a72..eb9d2da 100644
--- a/src/Script/Input.php
+++ b/src/Script/Input.php
@@ -21,25 +21,7 @@ class Input
*
* @var string
*/
- protected $shortOpts = 'f:d::t::l::c::';
-
- /**
- * Available CLI options
- * f filename - input file with the vendors data
- * d day - delivery day (dd/mm/yy)
- * t time - delivery time in 24h format (hh:mm)
- * l location - delivery location (postcode without spaces, e.g. NW43QB)
- * c covers - number of people to feed
- *
- * @var string
- */
- protected $longOpts = [
- 'filename:',
- 'day::',
- 'time::',
- 'location::',
- 'covers::'
- ];
+ protected $availableOptions = 'f:d::t::l::c::';
/**
* The loaded CLI options
@@ -66,7 +48,7 @@ class Input
*/
protected function loadOptions()
{
- $this->options = getopt($this->getShortOptionString(), $this->getLongOptionString());
+ $this->options = getopt($this->getOptionString());
if (!array_key_exists('f', $this->options)) {
throw new Exception('Filename Option `-f` is required');
@@ -92,21 +74,11 @@ class Input
* @author Phil Burton <phil@pgburton.com>
* @return string
*/
- public function getShortOptionString(): string
+ public function getOptionString(): string
{
- return $this->shortOpts;
+ return $this->availableOptions;
}
- /**
- * Return the option string for the options we want to load
- *
- * @author Phil Burton <phil@pgburton.com>
- * @return string
- */
- public function getLongOptionString(): array
- {
- return $this->longOpts;
- }
/**
* Return an option value