Thursday, 4 August 2016

Injeqt 1.1 and testing Qt applications

I've developed Injeqt as a way to improve Kadu quality. Its code was filled by singletons and hidden dependencies. Now, with Injeqt 1.1 released and Kadu 4.0 getting close to release I can tell that I've fulfilled my goals.

First step in making Kadu testable was to get rid of singletons and replace them with injected objects. With quick grep I discovered that the phase ::instance() had more than 2600 occurrences with more than 150 singleton classes in core alone (not counting plugins). It took me almost two months just to add Injeqt setters to each class that used these singletons and fix things that broke during that phase.

One of immediately visible benefit of this effort was that dependencies between classes were suddenly obvious (just look at header file for INJEQT_SET setters). And what follows - realization that some of them do not make any sense at all. And some classes have way too much dependencies (several classes with 10 or more dependencies and tens of classes with over 5). So its a good starting point for refactoring.

But you can't just get a 500000 lines project and refactor it. So I did what I think is the most reasonable way to it - refactor as you go (and add unit tests!).

This brings us to the core of this post - how easy it is to test classes and services using Injeqt.

First feature that I've added with this mindset was JumpList support on Windows. JumpList are additional menu items that shows in context menu over taskbar buttons, just like here:

Idea was simple - for Kadu it should display all currently open and recently used chats in two groups. This feature requires two services - OpenChatRepository and RecentChatRepository - these holds lists of open/recent chats (just wrapped sets with signals in reality). As these classes didn't exist at this time, I've implemented them and added tests (as these classes do not depend on anything, Injeqt is not used there).

Then more interesting things came - JumpList abstract class to act as an adaptor for Qt's QWinJumpList and WindowsJumpListService to to handle the chat repositories and the JumpList instance. Thanks to JumpList being an abstract interface it was easy to create JumpListStub and test the whole thing in windows-jump-list-service.test.cpp file. The core of this tests is in makeInjector method that contains private class module with all classes required to execute tests - including our stub class:

WindowsJumpListServiceTest::makeInjector() const
  class module : public injeqt::module

  auto modules =

  return injeqt::injector{std::move(modules)};

So I was able to recreate all required dependencies for WindowsJumpListService with ease. If OpenChatRepository or RecentChatRepository had their own dependencies it would be neccessary to mock them too, but fortunately it was not the case.

If you would like to test Injeqt if your own project or if you just have any questions, feel free to send me email and I'll be happy to answer.

Friday, 8 January 2016

Injeqt 1.1 is coming

After some hiatus (summer is time for riding a bike, not for spending evenings at home writing open-source code) I've moved Kadu few steps forward. New version - 4.0 - will require some more functionalities from Injeqt dependency injection library. So a few new had been added. Most of them for plugin support. I'll give a short description of each of them and then show you how these works together.


I've promised subinjectors when Injeqt 1.0 was released. And now these are available. In short - you can create new injector with new modules and classes that also gains all knowledge and instance of another injector (or injectors).

In Kadu this means that each plugin can new have its own injector and use all of Kadu classes and services in a nice way (using INJEQT_SET setters).


It is quite frequent to run some code after all required objects were injected into newly created one. Think of that as of two-step initialization (in that case it is not as bad as most people describe it, do not be scared). Slots marked with INJEQT_INIT tag will do just that - be called after all INJEQT_SET/INJEQT_SETTER slots.

INJEQT_DONE marked slots that will be called before any object created by injector is destructed. It allows for cleanup, writing files do disc and do other stuff without worrying about availability of other objects (such code can not be run from destructors, because Injeqt does not guarantee anything about order of object destruction).

In Kadu INJEQT_INIT methods are used to connects slots and signals of services and to do loading/storing data.


It is a new name for INJEQT_SETTER. Just to match grammar of INJEQT_INIT and INJEQT_DONE.


Now Injeqt allows you to select when given object will be instantiated. If it is tagged with INJEQT_INSTANCE_ON_DEMAND (default) the behavior will be the same as with Injeqt 1.0 - object will be first instantiated when it is needed. If class is tagged with INJEQT_INSTANCE_IMMEDIATE - object will be instantiated as soon as possible (before injeqt::injector constructor finishes). Useful for services that works on their own using signals from other services. In Kadu all main plugin objects are marked with INJEQT_INSTANCE_IMMEDIATE, so there is no need to manually create them after plugin is loaded and plugin's injector is created.

inject_into method

Sometimes you create object manually, but still want to put injectable objects into it. Just call injeqt::injector::injeqt_into(QObjec *) on it and you are done.

In Kadu this is mainly used to allow access to Kadu services by dynamically created widgets.

Usage in Kadu

Now I'll show you real-life example of how it all works together.

Lets get a quick overview on how Kadu plugins were loaded in the past (like 3.x releases).

class PluginRootComponent
  virtual bool init() = 0;
  virtual void done() = 0;

Q_DECLARE_INTERFACE(PluginRootComponent, "im.kadu.PluginRootComponent")
This is the class that each plugin must implement and export. You can see example implementation for OTR encryption plugin in otr-plugin.cpp file. As you can see it uses init() method to initialize its own injector, connect some of its signals and slots (unfortunately, Injeqt can not do it for you yet). Some objects from Kadu core are retrieved using Core::instance() calls (this is one thing that I'm fixing currently). And the done() method is used to remove OTR objects from Kadu services. Fortunately the Injeqt takes care of objects created with OTR injector. The last important part are PluginRootComponentHandler class:
  PluginRootComponent *pluginRootComponent) :

PluginRootComponentHandler::~PluginRootComponentHandler() noexcept
And the ActivePlugin class:
ActivePlugin::ActivePlugin(const QString &pluginName) :
So, finally, the steps are:
  1. load .dll or .so file
  2. create PluginRootComponent instance from it using Qt QPluginLoader
  3. call init() method on the instance, it creates its own objects and connects to Kadu core classes with awkward ::instance() calls (either Core::instance()->className() or className::instance()
  4. before unloading call done() method
In comparison, Kadu 4.x uses different method for that. PluginRootComponent is replaced with PluginModulesFactory:
class KADUAPI PluginModulesFactory : public QObject

  explicit PluginModulesFactory(QObject *parent = nullptr);
  virtual ~PluginModulesFactory();

  virtual std::vector<std::unique_ptr<injeqt::module>>
    createPluginModules() const = 0;
  virtual QString parentInjectorName() const;


Q_DECLARE_INTERFACE(PluginModulesFactory, "im.kadu.PluginModulesFactory")
Its only job is to create list of Injeqt modules. Implementation of this class is usually fairly simple:
OtrPluginModulesFactory::createPluginModules() const
  auto modules = std::vector<std::unique_ptr<injeqt::module>>{};

  return modules;
Then the injector is created and stored in PluginLoader class using following code:
injeqt::injector{std::vector<injeqt::injector *>{parentInjector},
And that is all that is needed from Kadu core. Now please look at new otr-plugin-object.h and otr-plugin-object.cpp files. There are few things to be seen in OtrPluginObject class:
  1. it is marked with INJEQT_INSTANCE_IMMEDIATE - it means it will be instantiated as soon as plugin is loaded and injector is created
  2. it has INJEQT_SET slots with Otr* objects (that come from OtrModule) and with other objects that comes from Kadu core - it is possible because of adding parentInjector into injeqt::injector constructor - we got rid of some of ::instance() calls
  3. it has INJEQT_INIT and INJEQT_DONE methods to set up and shut down the plugin - these two are called by Injeqt and replaces manually called init() and done() methods of PluginRootComponent


I think that Injeqt is going into good direction. It makes working with such a big project as Kadu a bit easier each time it is itself improved. In future I hope for two more things to be implemented in it: INJEQT_SIGNAL and INJEQT_SLOT tags that will allow to automatically connects slots and signals of Injeqt-created objects and something like INJEQT_ADD and INJEQT_REMOVE to simplify creating repository/registry-like classes. Maybe one of these feature will be added to Injeqt 1.2. After adding both of them, I could remove most of INJEQT_INIT and INJEQT_DONE methods from plugins.

Tuesday, 31 March 2015

End of Facebook Chat support

This is sad announcement. Kadu 3 will have its Facebook Chat support removed. There will be no longer possibility to add or use Facebook accounts and existing accounts will stop working. It is not Kadu fault. Facebook is closing its XMPP gates on 1.05.2015 [1] and their own protocol is not accessible for third party applications.


Tuesday, 3 March 2015

Moved to Gitlab

As you may know, Gitorious is merging with Gitlab. That means Kadu repository was also moved there: Github repository will be kept as mirror.

Saturday, 7 February 2015

Kadu nightly for Windows

If you are interested in testing Kadu we have great news for you: since today nightly Windows builds of 2.0 and 3.0 are available under Enjoy!

Thursday, 5 February 2015

New development model

Since Kadu 1.0 I'm working with new development model. It was first described in On versioning post. Its basic idea is very simple: release often, underpromise and overdeliver. Thanks to this 1.0 series had already 5 bugfix releases (last one, 1.5, was released just two weeks ago), 2.0 is almost released and work on 3.0 is underway.

Work on 2.0 was started very quickly around 1.0 release (to be completely honest, most of Qt5 port work was done by beevvy a long time ago). I didn't made big plans for it - just finish Qt5 port and add a few small features (and, of course, fix as much bugs as possible). And now it is almost release ready (rc2 will be available this weekend) and work on Kadu 3.0 is already progressing very nicely (this time with 100% support of file transfers in Gadu Gadu).

This is possible thanks to change of my own mentality (underpromise instead of overpromise) and to much improved source code quality - it is easier to make changes than 10 to 5 years ago. Also openSUSE Build Service is a great help - working Windows installer can be available just a hour after any commit.

So, get ready for 2.0 and for 3.0 testing!

Saturday, 24 January 2015

Injeqt 1.0.0

There is not much to say. I'm working with Injeqt (Qt dependency injection library) for some time now, preparing to release Kadu 2.0, and I've not encountered any problems at all. It is great to have only one feature and have full tests coverage for it. So here it is, 1.0.0 release!

I really enjoy using this small library, but I've also learned that I wish it have some more features:


I would like to use main Kadu injector in plugins code in a normal way. I would like to have a class with following header file and setters invoked by injector:

class ChatNotifier : public Notifier
private slots:
  INJEQT_SETTER void setChatWidgetRepository(
    ChatWidgetRepository *chatWidgetRepository);
  INJEQT_SETTER void setFormattedStringFactory(
    FormattedStringFactory *formattedStringFactory);

auto plugin_injector = injeqt::injector(
  plugin_modules, main_injector);
auto notifier = plugin_injector.get<ChatNotifier>();

Currently it is not possible - list of classes supported by injector is immutable and set on injector creation. And class ChatNotifier need to be added later, as it is in dynamically loaded plugin. So this code must be used:

class ChatNotifier : public Notifier
  void setChatWidgetRepository(
    ChatWidgetRepository *chatWidgetRepository);
  void setFormattedStringFactory(
    FormattedStringFactory *formattedStringFactory);

auto notifier = new ChatNotifier{this};

Subinjectors will solve this problem. Injectors will be able to have a parent injector and known all of its objects so it will be able to use them in an easy way.

As this is the feature that I miss most, it will be included in Injeqt 1.1 that will be released just before Kadu 3.0 (hopefully in about 3 or 4 months).


Injeqt should have an option to recognize matching signals and slots in objects that it creates and connect them automatically. I'm not 100% about the semantics of it (should it create objects just to connect to them even if application does not use them yet or should it wait for application to ask for an object to create it and connect). This is much more complicated to implement than subinjectors, so it is postponed to some next release.