Archive for the 'Software' category

Ack in vim

published on December 09, 2014.

I started using vim 3, 4 years ago. The way I use it is that I started out with no plugins and with a handful of lines in .vimrc. It is far too easy to cram all kind of stuff into it and then get lost in the myriads of key combinations. To prevent that, I decided to slowly add in bits and pieces I find lacking in my day to day usage of vim. Also allows me to first learn the editor and later the plugins.

Today was an exceptional day as I added not one, but two plugins to vim! And that is a big change for me as the total number of plugins I now use is 4.

The first one I added is ack.vim. It’s a nice little plugin to run ack from within vim and show the results in a split window. It’s rather easy to use, one just basically types :Ack search_string and that’s it. The one thing I immediately disliked is that it sort of gets lost in the subdirectories of a project.

A quick google search found a solution for that little problem as well: vim-rooter. It doesn’t do much, just changes the current working directory of vim to the project root when you open a file.

And that’s basically it. Nice and fast searching with ack from vim.

Tags: ack, vim, plugins, rooter.
Categories: Development, Software, Programming.

Saturday night hack - coords

published on March 24, 2013.

When I was just starting out learning programming, everything was so simple. I did not care about design patterns and best practices and unit tests and how will users use that piece of code. Hell, I did not even know those things exist. I was having fun, I was learning, I was free to do whatever I wanted to do, I was playing, I was like a child. Not that there is something wrong caring about those things now, but then I was able to put out a piece of code that was fixing a core of one problem I had and that was it. Once I was done with that, I would move on to the next problem. For a long time now I was missing that feeling of not caring, just fix the damn problem and move on. Just to slap together some crappy piece of code, use it once or twice and then forget about it.

And that was exactly what I did last night. I sat down and in some five or six hours I put together coords. It is an ugly as hell little pygtk application, void of any good practices, no tests, just a few comments here and there and that’s it. And I had fun writing it! I completely lost track of time while hacking, got into the zone and today, after some six hours of sleep I woke up feeling like I was on a vacation for a week.

The application itself doesn’t do much, it helps determine coordinates on your desktop. Start the application, click “track”, drag the mouse from the top-left corner you’re interested in to the bottom-left one and that’s it. The entire functionality is shown in this ten second long gif that runs somewhere here on the page. The best part is that it actually solves a problem I had, it helps me determine coordinates on my desktop and then I can use those coordinates for byzanz-record. I loved every second I spent hacking on this.

Best part is that even this little application had a quite an interesting challenge to solve, namely, to determine the position of the mouse anywhere on the screen. It’s no big deal to determine the position of the mouse inside your application, but once you want to break out of it, well, it gets bit tricky.

With pygtk one can only subscribe to events that happen inside the application itself. To go lower than that one needs to use a different library, something like xlib (python-xlib from python). After much poking around I found a way to do it from pygtk itself. It is possible to get hold of the root window instance, which is created by the X server itself (you can’t create a root window from an application, or make an application be a root window, afaik). Once you have the root window, grab the pointer, and then filter events you are interested in on the root window before they get sent from the X server to gtk. Or at least that is how I understood this whole process. While having control over the pointer, get the mouse coordinates from the time left button is pressed till the time it is released. Don’t forget to ungrab/release the pointer once your done. And that’s all there is to it, more or less.

The interesting parts are:

def start_tracking(self, widget, data=None):
    mask = gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK
    self.root_window = gtk.gdk.get_default_root_window()
    gtk.gdk.pointer_grab(self.root_window, False, mask)
    self.root_window.add_filter(self.track_region, self.region)
def track_region(self, event, region):
    x, y, flags = event.window.get_pointer()
    if 'GDK_BUTTON1_MASK' in flags.value_names \
            and region.track_started == False:
        region.start_x = x
        region.start_y = y
        region.track_started = True
        region.track_ended = False
    if 'GDK_BUTTON1_MASK' not in flags.value_names \
            and region.track_started == True:
        region.end_x = x
        region.end_y = y
        region.track_ended = True
        region.track_started = False
        # ungrab the pointer so we get control back
        gtk.gdk.pointer_ungrab()
        self.show_region_values(region)
    return gtk.gdk.FILTER_CONTINUE

Isn’t it ugly? Very. But it works and it solves the problem I had. Btw you can check out the code on github to have a bit more context for all this.

Happy hackin’!

When a package update goes wrong

published on February 06, 2013.

I am running Fedora 17 on my laptop, and yesterday there were some packages to update. Nothing unusual, updates on Fedora are quite frequent and, up until yesterday, there was not a single problem I remember with any update. And it was a small update, four packages in total. What could possibly go wrong, right?

After a reboot an odd thing happened. My laptop did not automatically connect to the wifi. Huh. So I clicked on the little network manager icon to pick the wifi. The list of scanned wifis was empty. Not a single network on the list. Then I did all the usual things one could do in a situation like this - turn on/off the wifi via the network manager, turn on/off the wifi via the keyboard shortcut, reboot the laptop a couple of times. Still nothing. At this point I started panicking.

I started suspecting the update. But I have no idea what packages were actually updated, what those packages do, or how I could see what packages were updated. After a bit of a googling from my phone, the answer was yum history. Apparently, this command will list recent changes to the system done by yum. Each change has a Transaction ID. More information about each change can be get with yum history info TID, where TID would be the transaction ID of the change you’re after. That will nicely list when did the change occur, which user made the changes, and what packages were affected in what way by that change.

One package caught my eye, called crda. It was updated from version 1.1.2 to 1.1.3. Google told me that crda has something to do with wireless. So, that was probably the culprit of my broken wireless. I started searching for possible bugs for this, or maybe even a workaround or a fix, but to no avail. I am not really good at debugging things like this, so I started looking for a way to somehow revert the update to this package and hopefully fix my wireless problems.

Yet again Google was involved and yet again yum history came to rescue. Apparently, besides tracking changes to the packages, it can also undo these changes: yum history undo TID, where TID is the ID of the transaction you want undone. It will try to undo changes to all packages, and in my case, it failed to undo some (hi Java!), but the crda package was reverted back to version 1.1.2 and after another reboot, the wireless was up and running once again, like nothing happened.

Yey for yum!

I have submitted a bug to Fedora’s bugzilla to hopefully figure out what went wrong and help the developers find a fix for this.

Tags: linux, fedora, packages, yum, history, undo.
Categories: Development, Software.

Gnucash 4.2 with SQLite3 on GNU/Linux

published on January 22, 2013.

For a while I was trying to figure out how to convert the Gnucash XML file to an SQLite3 database. From version 4.2, Gnucash supports PostrgreSQL, MySQL and SQLite3. Since then, the conversion is apparently simple as choosing File -> Save As … and picking a different data format. Thing is, my Gnucash instance didn’t have that! After some google-fu, turns out I was missing a library called libdbi-dbd-sqlite. After installing the missing library, suddenly the save works as it should. Why Gnucash didn’t pull this dependency (even if it’s optional) when I first installed it, is beyond me. But it’s there now and I can be on my marry way to draw fancy graphs with all this easily accessible, sweet data.

Tags: xml, gnucash, sqlite3.
Categories: Software, Development.

Unit testing Zend Framework 2 modules

published on September 15, 2012.

Porting this blog to Zend Framework 2, I decided to write some unit tests as well, while I’m at it. Not that the current code base doesn’t have unit tests, just it doesn’t have much of it… Anyway, I’d like to show how to get unit tests for modules up and running, as well how to throw in Mockery in the mix, as it can help us greatly with mocking out objects. Some of the parts shown here probably could be written in a more cleaner/nicer way, especially the autoloading bit, but so far it works for me.

The phpunit.xml file is rather simple:

<phpunit bootstrap='./bootstrap.php' colors='true'>
    <testsuite name='ZF2 Module Test Suite'>
        <directory>.</directory>
    </testsuite>
    <filter>
        <whitelist>
            <directory suffix='.php'>../src/</directory>
        </whitelist>
    </filter>
    <listeners>
        <listener class="\Mockery\Adapter\Phpunit\TestListener"
            file="Mockery/Adapter/Phpunit/TestListener.php"></listener>
    </listeners>
</phpunit>

The Mockery TestListener, as I found out the hard way, is needed for Mockery to work properly. You might add in some more stuff, like generating code coverage reports, and the like.

In the bootstrap.php we set up the autoloading for the modules, the ZF2 library, and Mockery:

<?php
putenv('ZF2_PATH=' . __DIR__ . '/../../../vendor/ZF2/library');
include_once __DIR__ . '/../../../init_autoloader.php';
set_include_path(implode(PATH_SEPARATOR, array(
    '.',
    __DIR__ . '/../src',
    __DIR__ . '/../../SomeRequiredModule/src',
    __DIR__ . '/../../../vendor',
    get_include_path(),
)));
spl_autoload_register(function($class) {
    $file = str_replace(array('\\', '_'), DIRECTORY_SEPARATOR, $class) . '.php';
    if (false === ($realpath = stream_resolve_include_path($file))) {
        return false;
    }
    include_once $realpath;
});
$loader = new \Mockery\Loader;
$loader->register();

It assumes that the currently tested module lives inside a ZF2 application. If not, you’ll probably need to adjust the paths accordingly. It also assumes that the Mockery files are in the vendor/ directory.

Testing the service layer

Don’t want to get into a fight about terminology, but the service layer for me, is the layer that lives between the controller layers and the database layers. It allows for keeping other layers clean of business logic, and easier testing. These services implement the Zend\ServiceManager\ServiceLocatorAwareInterface, which greatly simplifies unit testing, as it is easier to replace concrete objects with mocks.

Let’s assume that we have a “post” service, which we can use to get the recent posts. The post service itself does not interact with the databse, but calls an AbstractTableGateway which does all the database work. A test case for this post service, to avoid database calls, should mock the AbstractTableGateway, and use the ServiceManager to replace the concrete implementation with the mock object. An example test case for this post service could look something like this:

<?php
namespace BlogModule\Service;
use PHPUnit_Framework_TestCase as TestCase;
use Zend\ServiceManager\ServiceManager;
use Zend\Db\ResultSet\ResultSet;
use \Mockery as m;
class PostTest extends TestCase
{
    protected $postService;
    /**
    * @var Zend\ServiceManager\ServiceLocatorInterface
    */
    protected $serviceManager;
    public function setup()
    {
        $this->postService = new Post;
        $this->serviceManager = new ServiceManager;
        $this->postService->setServiceLocator($this->serviceManager);
    }
    public function testGetRecentPosts()
    {
        $mock = m::mock('Blog\Model\Table\Post');
        $this->serviceManager->setService('blogModelTablePost', $mock);
        $result = array(
            array(
                'id' => 1,
                'title' => 'Foo',
            ),
        );
        $resultSet = new ResultSet;
        $resultSet->initialize($result);
        $mock->shouldReceive('getRecentPosts')
            ->once()
            ->andReturn($resultSet);
        $posts = $this->postService->getRecentPosts();
        $this->assertSame($posts, $resultSet);
    }
}

On line 18 we set the service manager to be used with the post service, on line 22 we create a mock object, and on line 23 we set that mock object in the service manager. We set some expectations on the mock object - what method should be called, how many times and what should it return. Finally we call the actual method that is being tested on the post service and assert that the returned result is correct.

Testing the database layer

For testing the database layer, that is the AbstractTableGateway implementations, I use a little… trick. I don’t actually test what is returned from the database, but that the correct Sql\Select objects are being called, with the correct parameters in a correct order. This, in turn, means that I trust the underlying Zend\Db code that in the end, it will assemble the correct SQL queries, but I also don’t have to bother with setting up a test database, and also the tests run faster, as they don’t actually call the database. An example test case, continuing our example of getting recent posts:

<?php
namespace Blog\Model\Table;
use PHPUnit_Framework_TestCase as TestCase;
use Zend\ServiceManager\ServiceManager;
use Zend\Db\Sql\Select;
use \Mockery as m;
class PostTest extends TestCase
{
    protected $postTable;
    protected $select;
    protected $tableName = 'blog_posts';
    public function setup()
    {
        $adapter = $this->getAdapterMock();
        $this->postTable = new Post($adapter);
        $this->select = m::mock(new Select($this->tableName));
        $this->postTable->setSelect($this->select);
    }
    public function testGetRecentPosts()
    {
        $this->select->shouldReceive('from')
            ->once()
            ->with($this->tableName)
            ->andReturn($this->select);
        $this->select->shouldReceive('where')
            ->once()
            ->with(array('published = ?' => 1))
            ->andReturn($this->select);
        $this->select->shouldReceive('order')
            ->once()
            ->with('id DESC')
            ->andReturn($this->select);
        $this->select->shouldReceive('limit')
            ->once()
            ->with(10)
            ->andReturn($this->select);
        $this->postTable->getRecentPosts();
    }
}

Here we create a mock adapter (the getAdapterMock method can be seen in this gist), and use that mock adapter in our AbstractTableGateway implementation. We also create a mock Sql\Select object and we set expectations on that mock Select object. As I said, this way of testing might not be the best way out there, but it did help me catch a bug where I failed to add the where clause on the actual Select object. Yey for Mockery! Oh, and please do note that the adapter mock might not work in all cases, but again, so far it worked nicely for me.

One other thing would probably be interesting to show how to test, and that’s the action controllers, but I haven’t got around to write any controllers yet, so I’ll probably leave that for part 2. Or you could do it for homework.

Happy hackin’!

Robert Basic

Robert Basic

Software developer making web applications better.

Let's work together!

I would like to help you make your web application better.

Robert Basic © 2008 — 2020
Get the feed