phpunit: method serves different output based argument

I had the issue that my test-double sent incorrect values when invoked with specific arguments.

It returned null on every request.

First I thought this mock would return null on every call, but that’s not the case. Then I stumbled on this post on StackOverflow https://stackoverflow.com/questions/12748607/phpunits-returnvaluemap-not-yielding-expected-results.

The solution: the map-array needs all parameter-values listed in every element. Even the optional ones. I had to add null values for the optional parameters!

use returnValueMap method to map the received arguments to an array.

function myMethod($name, $optional=null){
  // ...
}

// Define which value need to be returned when 
// called with argument 'x'
// first element is argument 'x'; the argument passed, 
// 2nd element is the optional argument of the function
// 3d element is what will be returned by the test-double
$map = [
  ['value1', null, $valueToReturn1],
  ['value2', null, $valueToReturn2]
];

$request->expects($this->any())
  ->method('getRepository')
  ->will($this->returnValueMap($map));

$request->getRepository('value1'); // will return $valueToReturn1

Without the null added to it, it won’t work.

Example for my mock with Symfony. This will return the relevant repository on a request for method getRepository and with returnvalues for arguments AppBundle:Valuation and AppBundle:ObjectInvolvement.

$map = [
    ['AppBundle:Valuation', $valuationRepository],
    ['AppBundle:ObjectInvolvement', $objectInvolvementRepository]
];
$entityManager->expects($this->any())
    ->method('getRepository')
    ->will($this->returnValueMap($map));

 

Too large textareas

The other day I noticed really large textareas on the website. The textarea contained all the text and a lot of whitespace after it. After a short investigation I noticed two libraries fiddling with the height of textareas on the website: autosize and autogrow (a CKEditor plugin).

As the names suggests, they grow your textareas to the size of the text so you don’t have to scroll inside the textarea itself.

Cause

The large textareas reside on tabs which are not visible on pageload. And it were these textareas which grew out of bounds.

The cause is the following:

When an HTML-element is hidden, it is not possible for javascript to accurately get it’s width. And the width is needed to calculate correct dimensions for the textarea.

As noted on the autosize website (at the bottom) there are few things you can do:

  • assign a set width in pixels to the textarea in your stylesheet
  • delay autosizing until the element is revealed:

    var ta = document.querySelector(‘textarea’); ta.addEventListener(‘focus’, function(){ autosize(ta); });

  • use the autosize.update method after the element is revealed

The textareas I was dealing with did not have the issue with autosize, but rather with the autogrow plugin from CKEditor. The cause is the same.

Solution

My solution was to initiate the CKeditor on all visible textareas on the page. By putting this initiation in a function, I could call this function again when the contents of a new (bootstrap3) tab were loaded. But then again, a tab itself can contain hidden elements as well. So as a third I used library VisSense to observe relevant textareas when they become (partly) visible. I added a callback on this function to initiate CKEditor whenever the field becomes visible.

<!-- include the VisSense library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vissense/0.10.0/vissense.min.js"></script>

// get all relevant textareas (eg: textareas which have the 
//attribute 'data-provide' with value 'wysiwyg')
let ckeditorElements = $('textarea[data-provide="wysiwyg"]');

// add a listener which instructs to add CKEditor when the 
// field comes into view
$(ckeditorElements).each(function (index, element) {
    VisSense.VisMon.Builder(VisSense(element))
        .on('visible', function (monitor) {
            addCKEditorToElement(element);
        })
        .build()
        .start();
});

 /**
 * Add CKEditor functionality to an HTML-element 
 * (usually a textarea)
 * @param element   HTML-element like $('div.some-class')
 */
function addCKEditorToElement(element)
{
   let ckeditorTemplate = wysiwygConfigSmall;

   CKEDITOR.config.extraPlugins = 'autogrow';

    // instruct CKEditor to takeover this textarea
    CKEDITOR.replace(element);
}

Symfony JsTranslationBundle shows javascript translations upon login

In order to benefit from the Symfony3 translations in javascript files, I use BazingaJsTranslationBundle from

I had the weirdest thing: whenever I logged out, cleared my cache, went to the login page and logged in, I got redirected to /translations which showed me the generated JSON file with the translations.

Cause: the login page tried to load the JSON translation because of my <script src="{{ url('bazinga_jstranslation_js', {}) }}?locales=en,nl"></script> script import. But that failed as security did not allow anonymous access to that URI.

Symfony registered the failed URL and, as I’m on the login page, redirected me to the url that first failed once I was logged in.

Solution: allow anonymous access to URI /translations.

In file app/config/security.yml I added the following:

access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/translations, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Ansible stat module

I use the Ansible stat module mostly for conditional statements.

For example, only when directory /var/www/phpmyadmin does not exist include the task for installing PHPMyAdmin.

Only when <directory> exists; <do this>

But of course, there are a lot of other uses for this module then the one I use most.

It does this by doing the following two things:

  1. get all system-information about the directory
  2. execute statement, depending on values from the fetched system-information

But there are a lot of uses for the stat module.

The official documentation for the stat module is on, ofcourse, the Ansible website: http://docs.ansible.com/ansible/stat_module.html

full example

# file: install.yml

# install PHPMyAdmin when it's not installed already
- name: PHPMyAdmin | check the need for installment
  stat:
    path: /var/www/html/phpmyadmin
  register: pma

# Only include the PHPMyAdmin installation-task when it's not installed yet
# e.g. the directory /var/www/html/phpmyadmin does not exist
- include: PHPMyAdmin | install
  when: pma.stat.isdir is not defined

As you can see, we’re checking against the variable pma which holds the stats information for our path /var/www/html/phpmyadmin. This variable holds a lot more then just the isdir property.

The full list of information returned by the Ansible stat module:

  • atime
  • attributes
  • charset
  • checksum
  • ctime
  • dev
  • executable
  • exists
  • gid
  • gr_name
  • inode
  • isblk
  • ischr
  • isdir
  • isfifo
  • isgid
  • islnk
  • isreg
  • issock
  • isuid
  • lnk_source
  • md5
  • mime_type
  • mode
  • mtime
  • nlink
  • path
  • pw_name
  • readable
  • rgrp
  • roth
  • rusr
  • size
  • uid
  • wgrp
  • woth
  • writeable
  • wusr
  • xgrp
  • xoth
  • xusr

I will continue to update this page as needed.

Ansible lineinfile module: unsupported parameter for module: path

Is Ansible giving you the error unsupported parameter for module: path when you’re using lineinfile?

Check your Ansible-version!

You probably used path (as of version 2.3) instead of dest.

$ ansible --version
ansible 2.2.1.0
  config file =
  configured module search path = Default w/o overrides

As the Ansible documentation states:

As of Ansible 2.3, the dest option has been changed to path as default, but dest still works as well.

Solution: change dest into path

This fixed it for me. Now I can ensure composer is in my path.

# file composer.yml

# add composer to $PATH
- lineinfile:
    regexp: 'export PATH=".*/project/vendor/bin.*"'
    line: 'export PATH="$PATH:/project/vendor/bin"'
    state: present
    dest: /home/vagrant/.bashrc

Explanation of the parts:

  • regexp: the regular expression to look for. The line that matches will be used for present or absent
  • line: this is the line that will be inserted/replaced into the file
  • state: whether or not line should be there. Tip: for advanced usage, look at backrefs for changing parts of the line.
  • dest: the file we want the line in

See the official documentation for more information.

Behat 3 + Mink + Selenium

Installation

We will be installing the following:

  • Behat version 3 – the testingframework
  • Mink – for controlling real webbrowsers to run your tests
  • PHPUnit – for using the handy ‘assert’ methods PHPUnit provides.
  • Selenium Standalone Server – this will act as a service to accept connections and map them to browsers.

Continue reading

PHP won’t show any errors, or just a blank page

Getting a white page (the infamous the white page of death) when you instruct your browser to open your website? Want to debug an error, but you don’t see error messages on the screen but you do in your logfiles?

Then you should enable the displaying of errors in PHP.

There are few ways you can do this. But the best (fool proof) way is to have this in your php.ini file:

; file /etc/php5/apache2/php.ini

; here goes other settings

display_errors = On

NB: Don’t forget to restart your webserver after changing PHP’s configuration for it to have effect: sudo service apache2 restart

Continue reading

Certified PHP developer – yet again!

Today I got certified for the Zend Certification PHP Engineer exam! My third ZCE certificate in a row!

Zend is the company behind the certification for the PHP scripting language and the Zend PHP-framework.

I am now certified for PHP version 5.5 (there was no 5.6 certification). Before that I passed the exams for PHP version 5.3 in 2013 and version 5 in 2007. And does that make me happy!

A new entry in the ZCPE Directory (formerly known as Zend Yellow Papers) has been reserved for me 🙂

Continue reading

1 4 5 6
>