From 0b225663e087fb0f1457941743c8bac0c73b8763 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 10 Apr 2019 23:34:16 +0100 Subject: [PATCH 01/20] Allow for passing multiple lists --- src/Model/Filter.php | 6 +++++- tests/Unit/Model/FilterTest.php | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Model/Filter.php b/src/Model/Filter.php index 86a2640..dd6686c 100644 --- a/src/Model/Filter.php +++ b/src/Model/Filter.php @@ -4,6 +4,9 @@ namespace Opdavies\GmailFilterBuilder\Model; class Filter { + /** @var string */ + const SEPARATOR = '|'; + /** * @var array */ @@ -100,12 +103,13 @@ class Filter /** * Filter a message if it was sent from a mailing list. * - * @param $value The mailing list address + * @param string|array $value The mailing list address * * @return $this */ public function fromList($value) { + $value = collect($value)->implode(self::SEPARATOR); $this->has("list:{$value}"); return $this; diff --git a/tests/Unit/Model/FilterTest.php b/tests/Unit/Model/FilterTest.php index 8de48fc..e7063f0 100644 --- a/tests/Unit/Model/FilterTest.php +++ b/tests/Unit/Model/FilterTest.php @@ -143,6 +143,11 @@ class FilterTest extends TestCase ['hasTheWord' => 'list:foobar'], $this->filter->fromList('foobar')->toArray() ); + + $this->assertEquals( + ['hasTheWord' => 'list:list-one.com|list-two.com'], + $this->filter->fromList(['list-one.com', 'list-two.com'])->toArray() + ); } /** From ec3ecb685c4036f8b572d596f9f14f5fb2721691 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 10 Apr 2019 23:38:43 +0100 Subject: [PATCH 02/20] Update email address --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index feff976..8b403ed 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "authors": [ { "name": "Oliver Davies", - "email": "opdavies@gmail.com" + "email": "oliver@oliverdavies.uk" } ], "require": { From 77b83edfaebe597cb02fc1401445d94ce52e7391 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 11 Apr 2019 00:09:42 +0100 Subject: [PATCH 03/20] Update import --- src/Console/Command/GenerateCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index a81fe46..a026129 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -2,7 +2,7 @@ namespace Opdavies\GmailFilterBuilder\Console\Command; -use Opdavies\GmailFilterBuilder\Builder; +use Opdavies\GmailFilterBuilder\Service\Builder; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; From e7d8f37800e10f4e892b3cc2382d957091ed60f5 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 11 Apr 2019 00:14:54 +0100 Subject: [PATCH 04/20] Add shortcuts to generate command --- bin/generate-filters.php | 0 src/Console/Command/GenerateCommand.php | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 bin/generate-filters.php diff --git a/bin/generate-filters.php b/bin/generate-filters.php old mode 100644 new mode 100755 diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index a026129..2952c2e 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -22,8 +22,8 @@ class GenerateCommand extends Command $this ->setName(self::NAME) ->setDefinition([ - new InputOption('input-file', null, InputOption::VALUE_OPTIONAL, 'The name of the PHP file containing your filters.', 'filters.php'), - new InputOption('output-file', null, InputOption::VALUE_OPTIONAL, 'The name of the XML file to generate.', 'filters.xml') + new InputOption('input-file', 'i', InputOption::VALUE_OPTIONAL, 'The name of the PHP file containing your filters.', 'filters.php'), + new InputOption('output-file', 'o', InputOption::VALUE_OPTIONAL, 'The name of the XML file to generate.', 'filters.xml') ]) ->setDescription('Generates XML for Gmail filters.') ; From 72ed0d6f2457391a9936bb75884d35d32ca7be07 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 11 Apr 2019 00:27:34 +0100 Subject: [PATCH 05/20] Update file loading methods --- src/Console/Command/GenerateCommand.php | 31 ++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 2952c2e..5586f96 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; class GenerateCommand extends Command { @@ -34,26 +35,30 @@ class GenerateCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - $inputFile = $input->getOption('input-file'); - $outputFile = $input->getOption('output-file'); - - if (file_exists(__DIR__.'/'.$inputFile)) { - $filters = require_once __DIR__.'/'.$inputFile; - } elseif (file_exists(__DIR__.'/../../../../../../'.$inputFile)) { - # Installed as a dependency within "vendor". - $filters = require_once __DIR__.'/../../../../../../'.$inputFile; - } else { - throw new \Exception('No filters.php file found.'); - } - $io = new SymfonyStyle($input, $output); try { - new Builder($filters, $outputFile); + new Builder($this->filters($input), $outputFile = $this->outputFile($input)); $io->success(sprintf('%s file generated.', $outputFile)); } catch (IOException $e) { $io->error($e->getMessage()); } } + + private function outputFile(InputInterface $input): string + { + return $input->getOption('output-file') ?? getcwd() . '/filters.xml'; + } + + private function filters(InputInterface $input): array + { + $fs = new Filesystem(); + + if (!$fs->exists($inputFile = $input->getOption('input-file') ?? getcwd() . '/filters.php')) { + throw new \RuntimeException('No input file found.'); + } + + return require_once $inputFile; + } } From a4c913ab38f291e2ee7e400820e656886461ba94 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 11 Apr 2019 00:54:59 +0100 Subject: [PATCH 06/20] Add more type hints and return types Fixes #20 --- src/Model/Filter.php | 46 ++++++++++++++--------------- src/Service/Builder.php | 20 +++++++------ src/Service/Partials.php | 6 ++-- tests/Unit/Service/PartialsTest.php | 8 ++--- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/Model/Filter.php b/src/Model/Filter.php index dd6686c..76b14ff 100644 --- a/src/Model/Filter.php +++ b/src/Model/Filter.php @@ -15,7 +15,7 @@ class Filter /** * @return static */ - public static function create() + public static function create(): self { return new static(); } @@ -25,7 +25,7 @@ class Filter * * @return $this */ - public function has($value) + public function has(string $value): self { $this->properties['hasTheWord'] = $value; @@ -37,7 +37,7 @@ class Filter * * @return $this */ - public function hasNot($value) + public function hasNot(string $value): self { $this->properties['doesNotHaveTheWord'] = $value; @@ -49,7 +49,7 @@ class Filter * * @return $this */ - public function from($values) + public function from($values): self { if (!empty($values)) { $this->properties['from'] = collect($values)->map(function ($value) { @@ -65,7 +65,7 @@ class Filter * * @return $this */ - public function to($values) + public function to($values): self { if (!empty($values)) { $this->properties['to'] = collect($values)->map(function ($value) { @@ -81,7 +81,7 @@ class Filter * * @return $this */ - public function subject($values) + public function subject($values): self { $this->properties['subject'] = collect($values)->map(function ($value) { return json_encode($value); @@ -93,7 +93,7 @@ class Filter /** * @return $this */ - public function hasAttachment() + public function hasAttachment(): self { $this->properties['hasAttachment'] = 'true'; @@ -107,7 +107,7 @@ class Filter * * @return $this */ - public function fromList($value) + public function fromList($value): self { $value = collect($value)->implode(self::SEPARATOR); $this->has("list:{$value}"); @@ -118,7 +118,7 @@ class Filter /** * @return $this */ - public function excludeChats() + public function excludeChats(): self { $this->properties['excludeChats'] = 'true'; @@ -130,7 +130,7 @@ class Filter * * @return $this */ - public function label($label) + public function label(string $label): self { $this->properties['label'] = $label; @@ -140,7 +140,7 @@ class Filter /** * @return $this */ - public function archive() + public function archive(): self { $this->properties['shouldArchive'] = 'true'; @@ -152,7 +152,7 @@ class Filter * * @return $this */ - public function labelAndArchive($label) + public function labelAndArchive(string $label): self { $this->label($label)->archive(); @@ -162,7 +162,7 @@ class Filter /** * @return $this */ - public function spam() + public function spam(): self { $this->properties['shouldSpam'] = 'true'; $this->properties['shouldNeverSpam'] = 'false'; @@ -173,7 +173,7 @@ class Filter /** * @return $this */ - public function neverSpam() + public function neverSpam(): self { $this->properties['shouldSpam'] = 'false'; $this->properties['shouldNeverSpam'] = 'true'; @@ -184,7 +184,7 @@ class Filter /** * @return $this */ - public function trash() + public function trash(): self { $this->properties['shouldTrash'] = 'true'; @@ -194,7 +194,7 @@ class Filter /** * @return $this */ - public function read() + public function read(): self { $this->properties['markAsRead'] = 'true'; @@ -204,7 +204,7 @@ class Filter /** * @return $this */ - public function star() + public function star(): self { $this->properties['shouldStar'] = 'true'; @@ -216,7 +216,7 @@ class Filter * * @return $this */ - public function forward($to) + public function forward(string $to): self { $this->properties['forwardTo'] = $to; @@ -226,7 +226,7 @@ class Filter /** * @return $this */ - public function important() + public function important(): self { $this->properties['shouldAlwaysMarkAsImportant'] = 'true'; @@ -236,7 +236,7 @@ class Filter /** * @return $this */ - public function notImportant() + public function notImportant(): self { $this->properties['shouldNeverMarkAsImportant'] = 'true'; @@ -248,7 +248,7 @@ class Filter * * @return $this */ - public function categorise($category) + public function categorise(string $category): self { $this->properties['smartLabelToApply'] = $category; @@ -261,7 +261,7 @@ class Filter * @return array * @deprecated toArray() */ - public function getProperties() + public function getProperties(): array { return $this->properties; } @@ -271,7 +271,7 @@ class Filter * * @return array */ - public function toArray() + public function toArray(): array { return $this->properties; } diff --git a/src/Service/Builder.php b/src/Service/Builder.php index 509fe37..40bc4c2 100644 --- a/src/Service/Builder.php +++ b/src/Service/Builder.php @@ -39,7 +39,7 @@ class Builder $this->build(); } - public function __toString() + public function __toString(): string { return $this->build(); } @@ -49,7 +49,7 @@ class Builder * * @return string */ - public function getXml() + public function getXml(): string { return $this->xml; } @@ -59,7 +59,7 @@ class Builder * * @return string */ - private function build() + private function build(): void { $prefix = "" . PHP_EOL . ""; $suffix = ''; @@ -82,11 +82,13 @@ class Builder * * @return string */ - private function buildEntry(Filter $filter) + private function buildEntry(Filter $filter): string { - $entry = collect($filter->getProperties())->map(function ($value, $key) { - return $this->buildProperty($value, $key); - })->implode(PHP_EOL); + $entry = collect($filter->toArray()) + ->map(function ($value, $key): string { + return $this->buildProperty($value, $key); + }) + ->implode(PHP_EOL); return collect(['', $entry, ''])->implode(PHP_EOL); } @@ -99,7 +101,7 @@ class Builder * * @return string */ - private function buildProperty($value, $key) + private function buildProperty($value, $key): string { if (collect(['from', 'to'])->contains($key)) { $value = $this->implode($value); @@ -114,7 +116,7 @@ class Builder /** * Implode values with the appropriate prefix, suffix and separator. */ - private function implode($value, $separator = '|') + private function implode($value, $separator = '|'): string { if (is_string($value)) { return $value; diff --git a/src/Service/Partials.php b/src/Service/Partials.php index 70fe0cb..472c092 100644 --- a/src/Service/Partials.php +++ b/src/Service/Partials.php @@ -14,7 +14,7 @@ class Partials * * @return array The loaded filters. */ - public static function load($directoryName = 'filters') + public static function load($directoryName = 'filters'): array { $files = static::getFilePattern($directoryName); @@ -23,7 +23,7 @@ class Partials return include $filename; }) ->flatten(1) - ->all(); + ->toArray(); } /** @@ -36,7 +36,7 @@ class Partials * * @return string The full path. */ - protected static function getFilePattern($directoryName) + protected static function getFilePattern($directoryName): string { return getcwd() . DIRECTORY_SEPARATOR . $directoryName . DIRECTORY_SEPARATOR . '*.php'; } diff --git a/tests/Unit/Service/PartialsTest.php b/tests/Unit/Service/PartialsTest.php index 802f1bf..d9ab241 100644 --- a/tests/Unit/Service/PartialsTest.php +++ b/tests/Unit/Service/PartialsTest.php @@ -18,9 +18,9 @@ class PartialsTest extends TestCase $this->assertCount(3, $filters); - $this->assertSame('foo@example.com', $filters[0]->getProperties()['from'][0]); - $this->assertSame('bar@example.com', $filters[1]->getProperties()['from'][0]); - $this->assertSame('baz@example.com', $filters[2]->getProperties()['from'][0]); + $this->assertSame('foo@example.com', $filters[0]->toArray()['from'][0]); + $this->assertSame('bar@example.com', $filters[1]->toArray()['from'][0]); + $this->assertSame('baz@example.com', $filters[2]->toArray()['from'][0]); } } @@ -29,7 +29,7 @@ class FakePartials extends Partials /** * {@inheritdoc} */ - protected static function getFilePattern($directoryName) + protected static function getFilePattern($directoryName): string { return __DIR__ . '/../../stubs/filters/*.php'; } From 0346f25f96d42c12893c800552f8fdd50aee7d69 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:08:19 +0100 Subject: [PATCH 07/20] Add GenerateFiltersTest --- .../Console/Command/GenerateFiltersTest.php | 51 +++++++++++++++++++ tests/fixtures/simple/input.php | 9 ++++ 2 files changed, 60 insertions(+) create mode 100644 tests/Unit/Console/Command/GenerateFiltersTest.php create mode 100644 tests/fixtures/simple/input.php diff --git a/tests/Unit/Console/Command/GenerateFiltersTest.php b/tests/Unit/Console/Command/GenerateFiltersTest.php new file mode 100644 index 0000000..cf3755b --- /dev/null +++ b/tests/Unit/Console/Command/GenerateFiltersTest.php @@ -0,0 +1,51 @@ +commandTester = new CommandTester(new GenerateCommand()); + $this->fs = new Filesystem(); + } + + protected function tearDown() + { + // Ensure that files generated during tests are removed to prevent + // failures on future runs. + $this->fs->remove([self::OUTPUT_FILENAME]); + } + + /** @test */ + public function it_converts_filters_from_php_to_xml() + { + $this->commandTester->execute([ + '--input-file' => self::INPUT_FILENAME, + '--output-file' => self::OUTPUT_FILENAME, + ]); + + $this->assertTrue($this->fs->exists(self::OUTPUT_FILENAME)); + + $expected = file_get_contents(__DIR__ . '/../../../fixtures/simple/output.xml'); + $result = file_get_contents(self::OUTPUT_FILENAME); + + $this->assertEquals(trim($expected), $result); + } +} diff --git a/tests/fixtures/simple/input.php b/tests/fixtures/simple/input.php new file mode 100644 index 0000000..5a8d77e --- /dev/null +++ b/tests/fixtures/simple/input.php @@ -0,0 +1,9 @@ +from('example.com') + ->labelAndArchive('Test'), +]; From e863de7133b3cddd37bf2e02bb032ff26d99e9c4 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:12:34 +0100 Subject: [PATCH 08/20] Add lint script --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 8b403ed..6e111bb 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ "sort-packages": true }, "scripts": { + "lint": "php-cs-fixer fix", "test": "phpunit" } } From 0779825f801e749ef1992ab1aa6d9f1a23e25ca1 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:20:24 +0100 Subject: [PATCH 09/20] Move services.yml --- config/services.yml => services.yml | 0 src/Container/Container.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename config/services.yml => services.yml (100%) diff --git a/config/services.yml b/services.yml similarity index 100% rename from config/services.yml rename to services.yml diff --git a/src/Container/Container.php b/src/Container/Container.php index 905a9e4..b846d9f 100644 --- a/src/Container/Container.php +++ b/src/Container/Container.php @@ -11,7 +11,7 @@ class Container public function __construct() { $this->containerBuilder = new ContainerBuilder(); - $loader = new YamlFileLoader($this->containerBuilder, new FileLocator(__DIR__.'/../../config')); + $loader = new YamlFileLoader($this->containerBuilder, new FileLocator(__DIR__.'/../../')); $loader->load('services.yml'); $this->containerBuilder->addCompilerPass(new CommandCompilerClass()); $this->containerBuilder->compile(); From 685fbe51885dab7aee511f828278f6a18c45fb23 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:27:51 +0100 Subject: [PATCH 10/20] Use class names for service names --- bin/generate-filters.php | 2 +- services.yml | 9 ++------- src/Console/Command/GenerateCommand.php | 1 + src/Container/CommandCompilerClass.php | 3 ++- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/bin/generate-filters.php b/bin/generate-filters.php index 985eac1..d3b85e8 100755 --- a/bin/generate-filters.php +++ b/bin/generate-filters.php @@ -13,6 +13,6 @@ if (file_exists(__DIR__.'/../vendor/autoload.php')) { $container = new Container(); /** @var Application $application */ -$application = $container->get('app.cli'); +$application = $container->get(Application::class); $application->setDefaultCommand(GenerateCommand::NAME); $application->run(); diff --git a/services.yml b/services.yml index 75f8706..b8352c3 100644 --- a/services.yml +++ b/services.yml @@ -1,13 +1,8 @@ services: - app.cli: - class: Symfony\Component\Console\Application + Symfony\Component\Console\Application: autowire: true - app.builder: - class: Opdavies\GmailFilterBuilder\Service\Builder - - app.generate.command: - class: Opdavies\GmailFilterBuilder\Console\Command\GenerateCommand + Opdavies\GmailFilterBuilder\Console\Command\GenerateCommand: autowire: true tags: - { name: ConsoleCommand } diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 5586f96..836492a 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -38,6 +38,7 @@ class GenerateCommand extends Command $io = new SymfonyStyle($input, $output); try { + // TODO: Inject this. new Builder($this->filters($input), $outputFile = $this->outputFile($input)); $io->success(sprintf('%s file generated.', $outputFile)); diff --git a/src/Container/CommandCompilerClass.php b/src/Container/CommandCompilerClass.php index 64f441a..5e447ea 100644 --- a/src/Container/CommandCompilerClass.php +++ b/src/Container/CommandCompilerClass.php @@ -2,6 +2,7 @@ namespace Opdavies\GmailFilterBuilder\Container; +use Symfony\Component\Console\Application; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -13,7 +14,7 @@ class CommandCompilerClass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - $definition = $container->findDefinition('app.cli'); + $definition = $container->findDefinition(Application::class); $taggedServices = $container->findTaggedServiceIds('ConsoleCommand'); foreach ($taggedServices as $id => $tags) { From b123dcf079fa721b9154372c78e80fb4a90c3550 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:30:58 +0100 Subject: [PATCH 11/20] Update test, add expanded option --- src/Console/Command/GenerateCommand.php | 3 ++- tests/Unit/Console/Command/GenerateFiltersTest.php | 5 +++-- tests/fixtures/simple/output-expanded.xml | 8 ++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/simple/output-expanded.xml diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 836492a..896de6f 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -24,7 +24,8 @@ class GenerateCommand extends Command ->setName(self::NAME) ->setDefinition([ new InputOption('input-file', 'i', InputOption::VALUE_OPTIONAL, 'The name of the PHP file containing your filters.', 'filters.php'), - new InputOption('output-file', 'o', InputOption::VALUE_OPTIONAL, 'The name of the XML file to generate.', 'filters.xml') + new InputOption('output-file', 'o', InputOption::VALUE_OPTIONAL, 'The name of the XML file to generate.', 'filters.xml'), + new InputOption('expanded', 'e', InputOption::VALUE_NONE, 'Whether to generate expanded XML.') ]) ->setDescription('Generates XML for Gmail filters.') ; diff --git a/tests/Unit/Console/Command/GenerateFiltersTest.php b/tests/Unit/Console/Command/GenerateFiltersTest.php index cf3755b..fb51675 100644 --- a/tests/Unit/Console/Command/GenerateFiltersTest.php +++ b/tests/Unit/Console/Command/GenerateFiltersTest.php @@ -34,16 +34,17 @@ class GenerateFiltersTest extends TestCase } /** @test */ - public function it_converts_filters_from_php_to_xml() + public function it_converts_filters_from_php_to_expanded_xml() { $this->commandTester->execute([ '--input-file' => self::INPUT_FILENAME, '--output-file' => self::OUTPUT_FILENAME, + '--expanded' => true, ]); $this->assertTrue($this->fs->exists(self::OUTPUT_FILENAME)); - $expected = file_get_contents(__DIR__ . '/../../../fixtures/simple/output.xml'); + $expected = file_get_contents(__DIR__ . '/../../../fixtures/simple/output-expanded.xml'); $result = file_get_contents(self::OUTPUT_FILENAME); $this->assertEquals(trim($expected), $result); diff --git a/tests/fixtures/simple/output-expanded.xml b/tests/fixtures/simple/output-expanded.xml new file mode 100644 index 0000000..5ab840f --- /dev/null +++ b/tests/fixtures/simple/output-expanded.xml @@ -0,0 +1,8 @@ + + + + + + + + From 875d67ae7495d5da4e397cd7ed1406a68acf4e6e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 21:33:56 +0100 Subject: [PATCH 12/20] Add output.xml --- tests/fixtures/simple/output.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/fixtures/simple/output.xml diff --git a/tests/fixtures/simple/output.xml b/tests/fixtures/simple/output.xml new file mode 100644 index 0000000..5ab840f --- /dev/null +++ b/tests/fixtures/simple/output.xml @@ -0,0 +1,8 @@ + + + + + + + + From 4c00155956b30fa4efe985e4ea2bb0ca9e0fb882 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 18 Apr 2019 23:48:04 +0100 Subject: [PATCH 13/20] Generated filters can be expanded --- src/Console/Command/GenerateCommand.php | 4 ++-- src/Service/Builder.php | 21 +++++++++++++------ .../Console/Command/GenerateFiltersTest.php | 16 ++++++++++++++ tests/Unit/Service/BuilderTest.php | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 896de6f..40af0e6 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -40,7 +40,7 @@ class GenerateCommand extends Command try { // TODO: Inject this. - new Builder($this->filters($input), $outputFile = $this->outputFile($input)); + new Builder($this->filters($input), $outputFile = $this->outputFile($input), true, $input->getOption('expanded')); $io->success(sprintf('%s file generated.', $outputFile)); } catch (IOException $e) { @@ -61,6 +61,6 @@ class GenerateCommand extends Command throw new \RuntimeException('No input file found.'); } - return require_once $inputFile; + return require $inputFile; } } diff --git a/src/Service/Builder.php b/src/Service/Builder.php index 40bc4c2..c96878d 100644 --- a/src/Service/Builder.php +++ b/src/Service/Builder.php @@ -29,12 +29,16 @@ class Builder */ private $xml; - public function __construct(array $filters, $outputFile = 'filters.xml', $writeFile = true) + /** @var bool */ + private $expanded; + + public function __construct(array $filters, $outputFile = 'filters.xml', $writeFile = true, $expanded = false) { $this->filesystem = new Filesystem(); $this->filters = $filters; $this->outputFile = $outputFile; $this->writeFile = $writeFile; + $this->expanded = $expanded; $this->build(); } @@ -61,14 +65,14 @@ class Builder */ private function build(): void { - $prefix = "" . PHP_EOL . ""; + $prefix = "" . $this->glue() . ""; $suffix = ''; $xml = collect($this->filters)->map(function ($items) { return $this->buildEntry($items); - })->implode(PHP_EOL); + })->implode($this->glue()); - $this->xml = collect([$prefix, $xml, $suffix])->implode(PHP_EOL); + $this->xml = collect([$prefix, $xml, $suffix])->implode($this->glue()); if ($this->writeFile) { $this->filesystem->dumpFile($this->outputFile, $this->xml); @@ -88,9 +92,9 @@ class Builder ->map(function ($value, $key): string { return $this->buildProperty($value, $key); }) - ->implode(PHP_EOL); + ->implode($this->glue()); - return collect(['', $entry, ''])->implode(PHP_EOL); + return collect(['', $entry, ''])->implode($this->glue()); } /** @@ -128,4 +132,9 @@ class Builder return sprintf('(%s)', collect($value)->implode($separator)); } + + private function glue() + { + return $this->expanded ? PHP_EOL : null; + } } diff --git a/tests/Unit/Console/Command/GenerateFiltersTest.php b/tests/Unit/Console/Command/GenerateFiltersTest.php index fb51675..59bca9f 100644 --- a/tests/Unit/Console/Command/GenerateFiltersTest.php +++ b/tests/Unit/Console/Command/GenerateFiltersTest.php @@ -33,6 +33,22 @@ class GenerateFiltersTest extends TestCase $this->fs->remove([self::OUTPUT_FILENAME]); } + /** @test */ + public function it_converts_filters_from_php_to_minified_xml() + { + $this->commandTester->execute([ + '--input-file' => self::INPUT_FILENAME, + '--output-file' => self::OUTPUT_FILENAME, + ]); + + $this->assertTrue($this->fs->exists(self::OUTPUT_FILENAME)); + + $expected = file_get_contents(__DIR__ . '/../../../fixtures/simple/output.xml'); + $result = file_get_contents(self::OUTPUT_FILENAME); + + $this->assertEquals(trim($expected), $result); + } + /** @test */ public function it_converts_filters_from_php_to_expanded_xml() { diff --git a/tests/Unit/Service/BuilderTest.php b/tests/Unit/Service/BuilderTest.php index 4c40fc2..e8f7695 100644 --- a/tests/Unit/Service/BuilderTest.php +++ b/tests/Unit/Service/BuilderTest.php @@ -20,7 +20,7 @@ class BuilderTest extends TestCase ->star() ->important(); - $result = new Builder([$filterA, $filterB], '', false); + $result = new Builder([$filterA, $filterB], '', false, true); $expected = << From fb5b4922287bcfbba7b4b6024e30c6fa7ec58f3b Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 00:36:36 +0100 Subject: [PATCH 14/20] Add return type --- src/Service/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/Builder.php b/src/Service/Builder.php index c96878d..0092b7b 100644 --- a/src/Service/Builder.php +++ b/src/Service/Builder.php @@ -133,7 +133,7 @@ class Builder return sprintf('(%s)', collect($value)->implode($separator)); } - private function glue() + private function glue(): ?string { return $this->expanded ? PHP_EOL : null; } From 739b86290bc654acee35ec2761c8ba455b55ac8e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 00:38:41 +0100 Subject: [PATCH 15/20] Add output.xml --- tests/fixtures/simple/output.xml | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/fixtures/simple/output.xml diff --git a/tests/fixtures/simple/output.xml b/tests/fixtures/simple/output.xml new file mode 100644 index 0000000..eebac51 --- /dev/null +++ b/tests/fixtures/simple/output.xml @@ -0,0 +1 @@ + From 640719256bdd6e4094e44d3a9e9113990f524929 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 00:39:31 +0100 Subject: [PATCH 16/20] Don't ignore XML files within fixtures --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 54fca72..d0300e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ composer.lock filters.php *.xml +!/tests/fixtures/*/*.xml From 6a9562aa70fc3f4583d59f3ef831ab15c9dd51ea Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 01:30:13 +0100 Subject: [PATCH 17/20] Create CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1b5d417 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## 2.x + +* [#21](https://github.com/opdavies/gmail-filter-builder/issues/21): Minify the generated XML by default From de9db84d6d8f699f3dcb4492e4a0165e252b9e3b Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 07:31:49 +0100 Subject: [PATCH 18/20] Update test names Fixes #19 --- tests/Unit/Model/FilterTest.php | 82 +++++++++++++++++------------ tests/Unit/Service/BuilderTest.php | 3 +- tests/Unit/Service/PartialsTest.php | 6 +-- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/tests/Unit/Model/FilterTest.php b/tests/Unit/Model/FilterTest.php index e7063f0..57e7223 100644 --- a/tests/Unit/Model/FilterTest.php +++ b/tests/Unit/Model/FilterTest.php @@ -26,9 +26,10 @@ class FilterTest extends TestCase } /** - * @covers ::has + * @test + * @covers::has */ - public function testHas() + public function can_filter_on_a_has_value() { $this->assertEquals( ['hasTheWord' => 'something'], @@ -37,9 +38,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::hasNot */ - public function testHasNot() + public function can_filter_on_a_has_not_value() { $this->assertEquals( ['doesNotHaveTheWord' => 'something'], @@ -48,9 +50,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::from */ - public function testFrom() + public function can_filter_based_on_the_sender() { // Ensure that we can set one from address. $this->assertEquals( @@ -66,20 +69,20 @@ class FilterTest extends TestCase } /** - * Test that no 'from' key exists if no values were entered. - * + * @test * @covers ::from */ - public function testNoFromPropertyExistsIfTheValueIsEmpty() + public function no_from_property_exists_if_the_value_is_empty() { $this->assertArrayNotHasKey('from', $this->filter->from('')->toArray()); $this->assertArrayNotHasKey('from', $this->filter->from([])->toArray()); } /** + * @test * @covers ::to */ - public function testTo() + public function can_filter_based_on_the_recipient() { $this->assertEquals( ['to' => ['foo@example.com']], @@ -92,31 +95,24 @@ class FilterTest extends TestCase ); } - /** - * Test that no 'to' key exists if values were entered. - */ - public function testNoToPropertyExistsIfTheValueIsEmpty() + /** @test */ + public function no_to_property_exists_if_the_value_is_empty() { $this->assertArrayNotHasKey('to', $this->filter->to('')->toArray()); $this->assertArrayNotHasKey('to', $this->filter->to([])->toArray()); } /** + * @test * @covers ::subject */ - public function testSubject() + public function can_filter_based_on_the_subject() { $this->assertEquals( ['subject' => '"Something"'], $this->filter->subject('Something')->toArray() ); - } - /** - * Test that multiple subject conditions can be added. - */ - public function testMultipleSubjectsCanBeAdded() - { $this->assertEquals( ['subject' => '"Test"|"Foo bar"'], $this->filter->subject(['Test', 'Foo bar'])->toArray() @@ -124,9 +120,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::hasAttachment */ - public function testHasAttachment() + public function can_filter_based_on_whether_there_is_an_attachment() { $this->assertEquals( ['hasAttachment' => 'true'], @@ -135,9 +132,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::fromList */ - public function testFromList() + public function can_filter_based_on_wether_it_was_sent_to_a_list() { $this->assertEquals( ['hasTheWord' => 'list:foobar'], @@ -151,9 +149,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::excludeChats */ - public function testExcludeChats() + public function chats_can_be_excluded() { $this->assertEquals( ['excludeChats' => 'true'], @@ -162,9 +161,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::label */ - public function testLabel() + public function labels_can_be_added() { $this->assertEquals( ['label' => 'Foo'], @@ -173,9 +173,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::archive */ - public function testArchive() + public function messages_can_be_archived() { $this->assertEquals( ['shouldArchive' => 'true'], @@ -184,9 +185,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::labelAndArchive */ - public function testLabelAndArchive() + public function messages_can_be_labelled_and_archived() { $this->assertEquals( ['shouldArchive' => 'true', 'label' => 'Foo'], @@ -195,9 +197,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::spam */ - public function testSpam() + public function messages_can_be_marked_as_spam() { $this->assertEquals( [ @@ -209,9 +212,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::neverSpam */ - public function testNeverSpam() + public function messages_can_be_marked_as_not_spam() { $this->assertEquals( [ @@ -223,9 +227,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::trash */ - public function testTrash() + public function messages_can_be_deleted() { $this->assertEquals( ['shouldTrash' => 'true'], @@ -234,9 +239,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::read */ - public function testMarkAsRead() + public function messages_can_be_marked_as_read() { $this->assertEquals( ['markAsRead' => 'true'], @@ -245,9 +251,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::star */ - public function testStar() + public function messages_can_be_starred() { $this->assertEquals( ['shouldStar' => 'true'], @@ -256,9 +263,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::forward */ - public function testForwardTo() + public function messages_can_be_forwarded() { $this->assertEquals( ['forwardTo' => 'foo@example.com'], @@ -267,9 +275,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::important */ - public function testMarkImportant() + public function messages_can_be_marked_as_important() { $this->assertEquals( ['shouldAlwaysMarkAsImportant' => 'true'], @@ -278,9 +287,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::notImportant */ - public function testMarkNotImportant() + public function messages_can_be_marked_as_not_important() { $this->assertEquals( ['shouldNeverMarkAsImportant' => 'true'], @@ -289,9 +299,10 @@ class FilterTest extends TestCase } /** + * @test * @covers ::categorise */ - public function testCategorise() + public function messages_can_be_categorised() { $this->assertEquals( ['smartLabelToApply' => 'Foo'], @@ -299,7 +310,8 @@ class FilterTest extends TestCase ); } - public function testMethodsCanBeChained() + /** @test */ + public function methods_can_be_chained() { $this->assertEquals( [ diff --git a/tests/Unit/Service/BuilderTest.php b/tests/Unit/Service/BuilderTest.php index e8f7695..715299f 100644 --- a/tests/Unit/Service/BuilderTest.php +++ b/tests/Unit/Service/BuilderTest.php @@ -8,7 +8,8 @@ use PHPUnit\Framework\TestCase; class BuilderTest extends TestCase { - public function testBuild() + /** @test */ + public function it_can_build_filters() { $filterA = (new Filter()) ->from(['foo@example.com', 'test@example.com']) diff --git a/tests/Unit/Service/PartialsTest.php b/tests/Unit/Service/PartialsTest.php index d9ab241..47a1b3c 100644 --- a/tests/Unit/Service/PartialsTest.php +++ b/tests/Unit/Service/PartialsTest.php @@ -8,10 +8,8 @@ use PHPUnit\Framework\TestCase; class PartialsTest extends TestCase { - /** - * Test loading partials from multiple partial files. - */ - public function testLoadingFiltersFromPartials() + /** @test */ + public function filters_can_be_loaded_from_partials() { /** @var Filter[] $filters */ $filters = FakePartials::load('filters'); From db55e76c318401f6c44fa283a8343e4eaa458155 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 07:32:37 +0100 Subject: [PATCH 19/20] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b5d417..8e6d3bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,4 +2,5 @@ ## 2.x +* [#19](https://github.com/opdavies/gmail-filter-builder/issues/19): Update test method names * [#21](https://github.com/opdavies/gmail-filter-builder/issues/21): Minify the generated XML by default From 2e8e58abd06de3bb9c833295aa8ae043400c013e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 19 Apr 2019 08:02:10 +0100 Subject: [PATCH 20/20] Add 2.2.0 in CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e6d3bd..eb49fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # CHANGELOG -## 2.x +## 2.2.0 + +Released 2019-04-19 * [#19](https://github.com/opdavies/gmail-filter-builder/issues/19): Update test method names * [#21](https://github.com/opdavies/gmail-filter-builder/issues/21): Minify the generated XML by default