Dbarratt has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/383498 )

Change subject: Increase Test Coverage to 100%
......................................................................

Increase Test Coverage to 100%

Update the code to support test cases and increase the code
coverage to 100%.

Bug: T177667
Change-Id: I1d8bbc5dc9469f72237f5bde36d5fbc6306bf985
---
M composer.json
A src/AbstractEquivset.php
M src/Command/GenerateEquivset.php
M src/Equivset.php
A src/EquivsetInterface.php
A tests/AbstractEquivsetTest.php
A tests/Command/GenerateEquivsetTest.php
M tests/EquivsetTest.php
A tests/MockEquivset.php
A tests/MockEquivsetTest.php
10 files changed, 743 insertions(+), 169 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/libs/Equivset 
refs/changes/98/383498/1

diff --git a/composer.json b/composer.json
index f3a4d76..9fad549 100644
--- a/composer.json
+++ b/composer.json
@@ -33,7 +33,8 @@
                "symfony/var-dumper": "^3.3",
                "phpunit/phpunit": "^4.8",
                "jakub-onderka/php-parallel-lint": "^0.9.2",
-               "jakub-onderka/php-console-highlighter": "^0.3.2"
+               "jakub-onderka/php-console-highlighter": "^0.3.2",
+               "mikey179/vfsStream": "^1.6"
        },
        "scripts": {
                "lint": [
diff --git a/src/AbstractEquivset.php b/src/AbstractEquivset.php
new file mode 100644
index 0000000..fa2981f
--- /dev/null
+++ b/src/AbstractEquivset.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset;
+
+/**
+ * Equivset
+ */
+abstract class AbstractEquivset implements EquivsetInterface, 
\IteratorAggregate {
+
+       /**
+        * Equivset
+        *
+        * @param array $data Equalvalent Set
+        */
+       public function __construct( array $data = [] ) {
+               $this->data = $data;
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @return array An associative array of equivalent characters.
+        */
+       public function all() {
+               return $this->data;
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @param string $value The string to normalize against the equivset.
+        *
+        * @return string
+        */
+       public function normalize( $value ) {
+               $data = $this->all();
+
+               return strtr( $value, $data );
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @param string $str1 The first string.
+        * @param string $str2 The second string.
+        *
+        * @return string
+        */
+       public function isEqual( $str1, $str2 ) {
+               return $this->normalize( $str1 ) === $this->normalize( $str2 );
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @param string $key The character that was used.
+        *
+        * @return bool If the character has an equivalent.
+        */
+       public function has( $key ) {
+               $data = $this->all();
+
+               return array_key_exists( $key, $data );
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @param string $key The character that was used.
+        *
+        * @return string The equivalent character.
+        *
+        * @throws \LogicException If character does not exist.
+        */
+       public function get( $key ) {
+               $data = $this->all();
+
+               if ( ! array_key_exists( $key, $data ) ) {
+                       throw new \LogicException( 'Equivalent Character Not 
Found' );
+               }
+
+               return $data[$key];
+       }
+
+       /**
+        * {@inheritdoc}
+        *
+        * @return \Traversable The complete Equivset.
+        */
+       public function getIterator() {
+               return new \ArrayIterator( $this->all() );
+       }
+
+}
diff --git a/src/Command/GenerateEquivset.php b/src/Command/GenerateEquivset.php
index 43edefb..02c4dba 100644
--- a/src/Command/GenerateEquivset.php
+++ b/src/Command/GenerateEquivset.php
@@ -29,6 +29,32 @@
 class GenerateEquivset extends Command {
 
        /**
+        * @var string
+        */
+       protected $dataDir;
+
+       /**
+        * @var string
+        */
+       protected $distDir;
+
+       /**
+        * Generate Equivset
+        *
+        * @param string $dataDir Data Directory
+        * @param string $distDir Distrobution Directory
+        */
+       public function __construct(
+               $dataDir = '',
+               $distDir = ''
+       ) {
+               parent::__construct();
+
+               $this->dataDir = $dataDir ? $dataDir : __DIR__ . '/../../data';
+               $this->distDir = $distDir ? $distDir : __DIR__ . '/../../dist';
+       }
+
+       /**
         * {@inheritdoc}
         */
        protected function configure() {
@@ -44,10 +70,7 @@
         * @return int Return status.
         */
        public function execute( InputInterface $input, OutputInterface $output 
) {
-               $dataDir = __DIR__ . '/../../data';
-               $distDir = __DIR__ . '/../../dist';
-
-               $lines = file( $dataDir . '/equivset.in' );
+               $lines = file( $this->dataDir . '/equivset.in' );
                if ( !$lines ) {
                        throw new \Exception( "Unable to open equivset.in" );
                }
@@ -80,7 +103,7 @@
                                        $line, $m
                                )
                        ) {
-                               $output->writeln( "Error: invalid entry at line 
$lineNum: $line" );
+                               $output->writeln( "<error>Error: invalid entry 
at line $lineNum: $line</error>" );
                                $exitStatus = 1;
                                continue;
                        }
@@ -92,11 +115,11 @@
                                        $output->writeln( "Bytes: " . strlen( 
$m['charleft'] ) );
                                        $output->writeln( bin2hex( $line ) );
                                        $hexForm = bin2hex( $m['charleft'] );
-                                       $output->writeln( "Invalid UTF-8 
character \"{$m['charleft']}\" ($hexForm) at " .
-                                               "line $lineNum: $line" );
+                                       $output->writeln( "<error>Invalid UTF-8 
character \"{$m['charleft']}\" ($hexForm) at " .
+                                               "line $lineNum: $line</error>" 
);
                                } else {
-                                       $output->writeln( "Error: left number 
({$m['hexleft']}) does not match left " .
-                                               "character ($actual) at line 
$lineNum: $line" );
+                                       $output->writeln( "<error>Error: left 
number ({$m['hexleft']}) does not match left " .
+                                               "character ($actual) at line 
$lineNum: $line</error>" );
                                }
                                $error = true;
                        }
@@ -106,11 +129,11 @@
                                $actual = Utils::utf8ToCodepoint( 
$m['charright'] );
                                if ( $actual === false ) {
                                        $hexForm = bin2hex( $m['charright'] );
-                                       $output->writeln( "Invalid UTF-8 
character \"{$m['charleft']}\" ($hexForm) at " .
-                                               "line $lineNum: $line" );
+                                       $output->writeln( "<error>Invalid UTF-8 
character \"{$m['charleft']}\" ($hexForm) at " .
+                                               "line $lineNum: $line</error>" 
);
                                } else {
-                                       $output->writeln( "Error: right number 
({$m['hexright']}) does not match right " .
-                                               "character ($actual) at line 
$lineNum: $line" );
+                                       $output->writeln( "<error>Error: right 
number ({$m['hexright']}) does not match right " .
+                                               "character ($actual) at line 
$lineNum: $line</error>" );
                                }
                                $error = true;
                        }
@@ -153,24 +176,24 @@
                        $jsonData + $setsByChar,
                        JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
                );
-               file_put_contents( $distDir . '/equivset.json', $data );
+               file_put_contents( $this->distDir . '/equivset.json', $data );
 
                // Serialized.
-               file_put_contents( $distDir . '/equivset.ser', serialize( 
$setsByChar ) );
+               file_put_contents( $this->distDir . '/equivset.ser', serialize( 
$setsByChar ) );
 
                // Text File.
-               touch( $distDir . '/equivset.txt' );
-               $textFile = fopen( $distDir . '/equivset.txt', 'w' );
+               touch( $this->distDir . '/equivset.txt' );
+               $textFile = fopen( $this->distDir . '/equivset.txt', 'w' );
                foreach ( $sets as $members ) {
                        fwrite( $textFile, implode( ' ', $members ) . PHP_EOL );
                }
                fclose( $textFile );
 
-               $text = 'Finished';
                if ( $exitStatus > 0 ) {
-                       $text .= ' with errors';
+                       $output->writeln( '<error>Finished with errors</error>' 
);
+               } else {
+                       $output->writeln( '<info>Finished</info>' );
                }
-               $output->writeln( $text );
 
                return $exitStatus;
        }
diff --git a/src/Equivset.php b/src/Equivset.php
index b3e95ea..515d901 100644
--- a/src/Equivset.php
+++ b/src/Equivset.php
@@ -21,9 +21,9 @@
 use Wikimedia\Equivset\Exception\EquivsetException;
 
 /**
- * Equivset
+ * Default Equivset
  */
-class Equivset implements \IteratorAggregate {
+class Equivset extends AbstractEquivset {
 
        /**
         * @var string
@@ -31,18 +31,14 @@
        protected $serializedPath;
 
        /**
-        * @var array
-        */
-       protected $data;
-
-       /**
         * Equivset
         *
         * @param array $data Equalvalent Set
+        * @param string $serializedPath Path of the serialized equivset array.
         */
-       public function __construct( array $data = [] ) {
-               $this->data = $data;
-               $this->serializedPath = __DIR__ . '/../dist/equivset.ser';
+       public function __construct( array $data = [], $serializedPath = '' ) {
+               parent::__construct( $data );
+               $this->serializedPath = $serializedPath ? $serializedPath : 
__DIR__ . '/../dist/equivset.ser';
        }
 
        /**
@@ -74,11 +70,10 @@
                        throw new EquivsetException( 'Serialized equivset is 
unreadable' );
                }
 
+               // file_get_contents() will not fail at this point since none 
of the
+               // conditions that can cause a failure can happen at this point.
+               // @see http://php.net/manual/en/function.file-get-contents.php
                $contents = file_get_contents( $this->serializedPath );
-
-               if ( $contents === false ) {
-                       throw new EquivsetException( 'Reading serialized 
equivset failed' );
-               }
 
                $data = unserialize( $contents );
 
@@ -88,59 +83,4 @@
 
                return $data;
        }
-
-       /**
-        * Normalize a string.
-        *
-        * @param string $value The string to normalize against the equivset.
-        *
-        * @return string
-        */
-       public function normalize( $value ) {
-               $data = $this->all();
-
-               return strtr( $value, $data );
-       }
-
-       /**
-        * Deteremines if an equivalent character exists.
-        *
-        * @param string $key The character that was used.
-        *
-        * @return bool If the character has an equivalent.
-        */
-       public function has( $key ) {
-               $data = $this->all();
-
-               return array_key_exists( $key, $data );
-       }
-
-       /**
-        * Get an equivalent character.
-        *
-        * @param string $key The character that was used.
-        *
-        * @return string The equivalent character.
-        *
-        * @throws \LogicException If character does not exist.
-        */
-       public function get( $key ) {
-               $data = $this->all();
-
-               if ( ! array_key_exists( $key, $data ) ) {
-                       throw new \LogicException( 'Equivalent Character Not 
Found' );
-               }
-
-               return $data[$key];
-       }
-
-       /**
-        * {@inheritdoc}
-        *
-        * @return \Traversable The complete Equivset.
-        */
-       public function getIterator() {
-               return new \ArrayIterator( $this->all() );
-       }
-
 }
diff --git a/src/EquivsetInterface.php b/src/EquivsetInterface.php
new file mode 100644
index 0000000..d6fb0ac
--- /dev/null
+++ b/src/EquivsetInterface.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset;
+
+/**
+ * Equivset
+ */
+interface EquivsetInterface {
+
+       /**
+        * Gets the equivset.
+        *
+        * @return array An associative array of equivalent characters.
+        */
+       public function all();
+
+       /**
+        * Normalize a string.
+        *
+        * @param string $value The string to normalize against the equivset.
+        *
+        * @return string
+        */
+       public function normalize( $value );
+
+       /**
+        * Determine if the two strings are visually equal.
+        *
+        * @param string $str1 The first string.
+        * @param string $str2 The second string.
+        *
+        * @return bool
+        */
+       public function isEqual( $str1, $str2 );
+
+       /**
+        * Deteremines if an equivalent character exists.
+        *
+        * @param string $key The character that was used.
+        *
+        * @return bool If the character has an equivalent.
+        */
+       public function has( $key );
+
+       /**
+        * Get an equivalent character.
+        *
+        * @param string $key The character that was used.
+        *
+        * @return string The equivalent character.
+        *
+        * @throws \LogicException If character does not exist.
+        */
+       public function get( $key );
+}
diff --git a/tests/AbstractEquivsetTest.php b/tests/AbstractEquivsetTest.php
new file mode 100644
index 0000000..83fcd53
--- /dev/null
+++ b/tests/AbstractEquivsetTest.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Equiveset
+ */
+abstract class AbstractEquivsetTest extends TestCase {
+
+       /**
+        * @var string
+        */
+       protected $class;
+
+       /**
+        * @var EquivsetInterface
+        */
+       protected $equivset;
+
+       /**
+        * @var array
+        */
+       protected $data = [
+               '0' => 'O',
+       ];
+
+       /**
+        * Gets the Equivset.
+        */
+       protected function getEquivset() {
+               if ( !$this->equivset ) {
+                       $this->equivset = new $this->class( $this->data );
+               }
+
+               return $this->equivset;
+       }
+
+       /**
+        * Test Get All.
+        */
+       public function testAll() {
+               $data = $this->getEquivset()->all();
+               $this->assertEquals( 'O', $data[0] );
+       }
+
+       /**
+        * Test Get All.
+        */
+       public function testNormalize() {
+               $this->assertEquals( 'O', $this->getEquivset()->normalize( '0' 
) );
+       }
+
+       /**
+        * Test Get All.
+        */
+       public function testIsEqual() {
+               $this->assertTrue( $this->getEquivset()->isEqual( '0', '0' ) );
+       }
+
+       /**
+        * Tests Traversable.
+        */
+       public function testTraversable() {
+               $this->assertInstanceOf( \Traversable::class, 
$this->getEquivset() );
+       }
+
+       /**
+        * Test Get Iterator.
+        */
+       public function testGetIterator() {
+               $data = $this->getEquivset()->getIterator();
+               $this->assertEquals( 'O', $data[0] );
+               $this->assertInstanceOf( \Traversable::class, $data );
+       }
+
+       /**
+        * Test Has.
+        */
+       public function testHas() {
+               $this->assertTrue( $this->getEquivset()->has( '0' ) );
+       }
+
+       /**
+        * Test Has Not.
+        */
+       public function testHasNot() {
+               $this->assertFalse( $this->getEquivset()->has( 'fail' ) );
+       }
+
+       /**
+        * Test Get.
+        */
+       public function testGet() {
+               $this->assertEquals( 'O', $this->getEquivset()->get( '0' ) );
+       }
+
+       /**
+        * Test Get Fail.
+        *
+        * @expectedException
+        */
+       public function testGetFail() {
+               $this->setExpectedException( \LogicException::class );
+
+               $this->getEquivset()->get( 'fail' );
+       }
+}
diff --git a/tests/Command/GenerateEquivsetTest.php 
b/tests/Command/GenerateEquivsetTest.php
new file mode 100644
index 0000000..10d61bf
--- /dev/null
+++ b/tests/Command/GenerateEquivsetTest.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset\Command;
+
+use org\bovigo\vfs\vfsStream;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Generate Equivset Command.
+ */
+class GenerateEquivsetTest extends TestCase {
+
+       /**
+        * Test Configuration
+        */
+       public function testConfigure() {
+               $command = new GenerateEquivset();
+
+               $this->assertEquals( 'generate-equivset', $command->getName() );
+       }
+
+       /**
+        * Test Mocked Execute.
+        */
+       public function testExecute() {
+               $in = "# Testing...\n30 0 => 4F O";
+               $out = [
+                       0 => 'O',
+               ];
+
+               $root = vfsStream::setup();
+               $data = vfsStream::newDirectory( 'data' )
+                       ->at( $root );
+               $file = vfsStream::newFile( 'equivset.in' )
+                       ->withContent( $in )
+                       ->at( $data );
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( $data->url(), $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+
+               $status = $command->execute( $input, $output );
+
+               $this->assertEquals( 0, $status );
+
+               $this->assertTrue( $dist->hasChild( 'equivset.ser' ) );
+               $this->assertTrue( $dist->hasChild( 'equivset.json' ) );
+               $this->assertTrue( $dist->hasChild( 'equivset.txt' ) );
+
+               $this->assertEquals( serialize( $out ), $dist->getChild( 
'equivset.ser' )->getContent() );
+       }
+
+       /**
+        * Test Live Execute.
+        */
+       public function testLiveExecute() {
+               // Write the output to memory.
+               $root = vfsStream::setup();
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( '', $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+
+               $status = $command->execute( $input, $output );
+
+               $this->assertEquals( 0, $status );
+
+               $this->assertTrue( $dist->hasChild( 'equivset.ser' ) );
+               $this->assertTrue( $dist->hasChild( 'equivset.json' ) );
+               $this->assertTrue( $dist->hasChild( 'equivset.txt' ) );
+
+               $output = unserialize( $dist->getChild( 'equivset.ser' 
)->getContent() );
+
+               $this->assertEquals( 'O', $output[0] );
+       }
+
+       /**
+        * Test Execute Fail Open
+        */
+       public function testExecuteFailOpen() {
+               $root = vfsStream::setup();
+               $data = vfsStream::newDirectory( 'data' )
+                       ->at( $root );
+               $file = vfsStream::newFile( 'equivset.in' )
+                       ->at( $data );
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( $data->url(), $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+
+               $this->setExpectedException( \Exception::class, 'Unable to open 
equivset.in' );
+               $command->execute( $input, $output );
+       }
+
+       /**
+        * Test Execute Fail Malformed
+        */
+       public function testExecuteFailMalformed() {
+               $in = "0 => 4F O";
+               $out = [
+                       0 => 'O',
+               ];
+
+               $root = vfsStream::setup();
+               $data = vfsStream::newDirectory( 'data' )
+                       ->at( $root );
+               $file = vfsStream::newFile( 'equivset.in' )
+                       ->withContent( $in )
+                       ->at( $data );
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( $data->url(), $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+               $output->method( 'writeln' )
+                       ->with( $this->logicalOr(
+                               $this->stringContains( 'Error: invalid entry' ),
+                               $this->stringContains( 'Finished with errors' )
+                       ) );
+               $status = $command->execute( $input, $output );
+
+               $this->assertEquals( 1, $status );
+
+               $this->assertNotEquals( serialize( $out ), $dist->getChild( 
'equivset.ser' )->getContent() );
+       }
+
+       /**
+        * Provide Not Matching Code Points.
+        */
+       public function provideNotMatchingCodePoints() {
+               return [
+                       [ 'left', '31', '31 0 => 4F O' ],
+                       [ 'right', '4', '30 0 => 4 O' ],
+               ];
+       }
+
+       /**
+        * Test Execute Fail Not Matching Codepoint
+        *
+        * @param string $side The left or right side
+        * @param string $number N being used
+        * @param string $in Equivset line
+        *
+        * @dataProvider provideNotMatchingCodePoints
+        */
+       public function testExecuteFailNotMatchingCodepoint( $side, $number, 
$in ) {
+               $out = [
+                       0 => 'O',
+               ];
+
+               $root = vfsStream::setup();
+               $data = vfsStream::newDirectory( 'data' )
+                       ->at( $root );
+               $file = vfsStream::newFile( 'equivset.in' )
+                       ->withContent( $in )
+                       ->at( $data );
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( $data->url(), $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+               $output->method( 'writeln' )
+                       ->with( $this->logicalOr(
+                               $this->stringContains( "Error: $side number 
($number) does not match" ),
+                               $this->stringContains( 'Finished with errors' )
+                       ) );
+
+               $status = $command->execute( $input, $output );
+
+               $this->assertEquals( 1, $status );
+
+               $this->assertNotEquals( serialize( $out ), $dist->getChild( 
'equivset.ser' )->getContent() );
+       }
+
+       /**
+        * Provide Invalid Chars
+        */
+       public function provideInvalidChar() {
+               return [
+                       [ '30 �� => 4F O' ],
+                       [ '30 0 => 4F ��' ],
+               ];
+       }
+
+       /**
+        * Test Execute Failure Invalid Charachter
+        *
+        * @param string $in Equivset line
+        *
+        * @dataProvider provideInvalidChar
+        */
+       public function testExecuteFailInvalidChar( $in ) {
+               $out = [
+                       0 => 'O',
+               ];
+
+               $root = vfsStream::setup();
+               $data = vfsStream::newDirectory( 'data' )
+                       ->at( $root );
+               $file = vfsStream::newFile( 'equivset.in' )
+                       ->withContent( $in )
+                       ->at( $data );
+               $dist = vfsStream::newDirectory( 'dist' )
+                       ->at( $root );
+
+               $command = new GenerateEquivset( $data->url(), $dist->url() );
+
+               $input = $this->getMockBuilder( InputInterface::class )
+                       ->getMock();
+               $output = $this->getMockBuilder( OutputInterface::class )
+                       ->getMock();
+               $output->method( 'writeln' )
+                       ->with( $this->logicalOr(
+                               $this->stringContains( 'Bytes' ),
+                               $this->stringContains( bin2hex( $in ) ),
+                               $this->stringContains( 'Invalid UTF-8 
character' ),
+                               $this->stringContains( 'Finished with errors' )
+                       ) );
+
+               $status = $command->execute( $input, $output );
+
+               $this->assertEquals( 1, $status );
+
+               $this->assertNotEquals( serialize( $out ), $dist->getChild( 
'equivset.ser' )->getContent() );
+       }
+}
diff --git a/tests/EquivsetTest.php b/tests/EquivsetTest.php
index fa37840..67b2df0 100644
--- a/tests/EquivsetTest.php
+++ b/tests/EquivsetTest.php
@@ -18,91 +18,18 @@
 
 namespace Wikimedia\Equivset;
 
-use PHPUnit\Framework\TestCase;
+use org\bovigo\vfs\vfsStream;
+use Wikimedia\Equivset\Exception\EquivsetException;
 
 /**
  * Equiveset
  */
-class EquivsetTest extends TestCase {
+class EquivsetTest extends AbstractEquivsetTest {
 
        /**
-        * Test Get All.
+        * @var string
         */
-       public function testAll() {
-               $equivset = new Equivset();
-
-               $data = $equivset->all();
-               $this->assertEquals( 'O', $data[0] );
-       }
-
-       /**
-        * Test Get All.
-        */
-       public function testNormalize() {
-               $equivset = new Equivset();
-
-               $this->assertEquals( 'O', $equivset->normalize( 0 ) );
-       }
-
-       /**
-        * Tests Traversable.
-        */
-       public function testTraversable() {
-               $equivset = new Equivset();
-
-               $this->assertInstanceOf( \Traversable::class, $equivset );
-       }
-
-       /**
-        * Test Get Iterator.
-        */
-       public function testGetIterator() {
-               $equivset = new Equivset();
-
-               $data = $equivset->getIterator();
-               $this->assertEquals( 'O', $data[0] );
-               $this->assertInstanceOf( \Traversable::class, $data );
-       }
-
-       /**
-        * Test Has.
-        */
-       public function testHas() {
-               $equivset = new Equivset();
-
-               $this->assertTrue( $equivset->has( 0 ) );
-       }
-
-       /**
-        * Test Has Not.
-        */
-       public function testHasNot() {
-               $equivset = new Equivset();
-
-               $this->assertFalse( $equivset->has( 'fail' ) );
-       }
-
-       /**
-        * Test Get.
-        */
-       public function testGet() {
-               $equivset = new Equivset();
-
-               $this->assertEquals( 'O', $equivset->get( 0 ) );
-       }
-
-       /**
-        * Test Get Fail.
-        *
-        * @expectedException
-        */
-       public function testGetFail() {
-               $this->setExpectedException( \LogicException::class );
-
-               $equivset = new Equivset();
-
-               $equivset->get( 'fail' );
-       }
+       protected $class = Equivset::class;
 
        /**
         * Provide Spoof Data.
@@ -131,7 +58,62 @@
        public function testCheckUnicodeString( $userName, $spooferName ) {
                $equivset = new Equivset();
 
-               $this->assertEquals( $equivset->normalize( $userName ), 
$equivset->normalize( $spooferName ) );
+               $this->assertTrue( $equivset->isEqual( $userName, $spooferName 
) );
+       }
+
+       /**
+        * Test Load
+        */
+       public function testLoad() {
+               $root = vfsStream::setup();
+               $file = vfsStream::newFile( 'equivset.ser' )
+                       ->withContent( serialize( $this->data ) )
+                       ->at( $root );
+               $equivset = new Equivset( [], $file->url() );
+
+               $this->assertEquals( $this->data, $equivset->all() );
+       }
+
+       /**
+        * Test Load
+        */
+       public function testLoadFailNoFile() {
+               $root = vfsStream::setup();
+               $equivset = new Equivset( [], $root->url() . '/missing' );
+
+               $this->setExpectedException( EquivsetException::class, 
'Serialized equivset is missing' );
+               $equivset->all();
+       }
+
+       /**
+        * Test Load
+        */
+       public function testLoadFailUnreadableFile() {
+               $root = vfsStream::setup();
+               $file = vfsStream::newFile( 'equivset.ser', 0000 )
+                       ->withContent( serialize( $this->data ) )
+                       ->at( $root );
+               $equivset = new Equivset( [], $file->url() );
+
+               $this->setExpectedException( EquivsetException::class, 
'Serialized equivset is unreadable' );
+               $equivset->all();
+       }
+
+       /**
+        * Test Load
+        */
+       public function testLoadFailUnseriableFile() {
+               $root = vfsStream::setup();
+               $file = vfsStream::newFile( 'equivset.ser' )
+                       ->withContent( '' )
+                       ->at( $root );
+               $equivset = new Equivset( [], $file->url() );
+
+               $this->setExpectedException(
+                       EquivsetException::class,
+                       'Unserializing serialized equivset failed'
+               );
+               $equivset->all();
        }
 
 }
diff --git a/tests/MockEquivset.php b/tests/MockEquivset.php
new file mode 100644
index 0000000..ebec96f
--- /dev/null
+++ b/tests/MockEquivset.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset;
+
+/**
+ * Mock Equivset
+ */
+class MockEquivset extends AbstractEquivset {
+}
diff --git a/tests/MockEquivsetTest.php b/tests/MockEquivsetTest.php
new file mode 100644
index 0000000..5ad57a9
--- /dev/null
+++ b/tests/MockEquivsetTest.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+namespace Wikimedia\Equivset;
+
+/**
+ * Equiveset
+ */
+class MockEquivsetTest extends AbstractEquivsetTest {
+
+       /**
+        * @var string
+        */
+       protected $class = MockEquivset::class;
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/383498
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1d8bbc5dc9469f72237f5bde36d5fbc6306bf985
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/libs/Equivset
Gerrit-Branch: master
Gerrit-Owner: Dbarratt <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to