Skip to content
John Long edited this page Nov 21, 2013 · 4 revisions

Examples for testing file modes

Let's take the Example class again and modify it a bit:

    <?php
    namespace org\bovigo\vfs\example;
    class FilemodeExample
    {
        /**
         * id of the example
         *
         * @var  string
         */
        protected $id;
        /**
         * a directory where we do something..
         *
         * @var  string
         */
        protected $directory;
        /**
         * file mode for newly created directories
         *
         * @var  int
         */
        protected $fileMode;
    
        /**
         * constructor
         *
         * @param  string  $id
         * @param  int     $fileMode  optional
         */
        public function __construct($id,  $fileMode = 0700)
        {
            $this->id       = $id;
            $this->fileMode = $fileMode;
        }
    
        /**
         * sets the directory
         *
         * @param  string  $directory
         */
        public function setDirectory($directory)
        {
            $this->directory = $directory . DIRECTORY_SEPARATOR . $this->id;
            if (file_exists($this->directory) === false) {
                mkdir($this->directory, $this->fileMode, true);
            }
        }
    
        // more source code here...
    }
    ?>

So how do we make sure that the new directory created in setDirectory() has the correct file mode? Without vfsStream a test could look like this:

    <?php
    namespace org\bovigo\vfs\example;
    class FileModeExampleTestCaseOldWay extends \PHPUnit_Framework_TestCase
    {
        /**
         * set up test environmemt
         */
        public function setUp()
        {
            if (file_exists(dirname(__FILE__) . '/id') === true) {
                rmdir(dirname(__FILE__) . '/id');
            }
        }
    
        /**
         * clear up test environment
         */
        public function tearDown()
        {
            if (file_exists(dirname(__FILE__) . '/id') === true) {
                rmdir(dirname(__FILE__) . '/id');
            }
        }
    
        /**
         * test correct file mode for created directory
         */
        public function testDirectoryHasCorrectDefaultFilePermissions()
        {
            $example = new FilemodeExample('id');
            $example->setDirectory(dirname(__FILE__));
            if (DIRECTORY_SEPARATOR === '\\') {
                // can not really test on windows, filemode from mkdir() is ignored
                $this->assertEquals(40777, decoct(fileperms(dirname(__FILE__) . '/id')));
            } else {
                $this->assertEquals(40700, decoct(fileperms(dirname(__FILE__) . '/id')));
            }
        }
    
        /**
         * test correct file mode for created directory
         */
        public function testDirectoryHasCorrectDifferentFilePermissions()
        {
            $example = new FilemodeExample('id', 0755);
            $example->setDirectory(dirname(__FILE__));
            if (DIRECTORY_SEPARATOR === '\\') {
                // can not really test on windows, filemode from mkdir() is ignored
                $this->assertEquals(40777, decoct(fileperms(dirname(__FILE__) . '/id')));
            } else {
                $this->assertEquals(40755, decoct(fileperms(dirname(__FILE__) . '/id')));
            }
        }
    }
    ?>

Again we need to have setUp() and tearDown() methods to make sure that before and after the test the directory does not exist. But the worst part are the testcases itself. First we have to separate if we are on a Windows platform - on windows new directories always will have 0777 as filemode, regardless of what mkdir() receives as parameter, making both test cases the same. But even if we are on a file system which has real file modes the assertion looks quite ugly and makes not clear on the first view what the assertion is about.

Again, we will use vfsStream to simplify and improve the test:

    <?php
    namespace org\bovigo\vfs\example;
    use org\bovigo\vfs\vfsStream;
    class FilemodeExampleTestCaseWithVfsStream extends \PHPUnit_Framework_TestCase
    {
        /**
         * @var  vfsStreamDirectory
         */
        private $root;

        /**
         * set up test environmemt
         */
        public function setUp()
        {
            $this->root = vfsStream::setup('exampleDir');
        }
    
        /**
         * test that the directory is created
         */
        public function testDirectoryIsCreatedWithDefaultPermissions()
        {
            $example = new FilemodeExample('id');
            $example->setDirectory(vfsStream::url('exampleDir'));
            $this->assertEquals(0700, $this->root->getChild('id')->getPermissions());
        }
    
        /**
         * test that the directory is created
         */
        public function testDirectoryIsCreatedWithGivenPermissions()
        {
            $example = new FilemodeExample('id', 0755);
            $example->setDirectory(vfsStream::url('exampleDir'));
            $this->assertEquals(0755, $this->root->getChild('id')->getPermissions());
        }
    }
    ?>

Again, no tearDown() method is required any more. Additionally we made the test independent from the OS - it's the same for all. And due to the usage of vfsStream methods the intention of the assertion gets more clear compared to the conventional test without vfsStream.

Clone this wiki locally