Skip to content

How To Get Midje Working With appengine-magic

Recently I’ve begun using a testing framework in Clojure called Midje. There are several other Clojure testing libraries including one that comes with Clojure. Midje does have an interesting syntax however and good support for mocking – although it doesn’t use that term. One particularly nice thing is it’s integration with Emacs. With quick keyboard shortcut I can easily run the current Midje test and see the results come up as comments right next to the test. Those comments can then be easily cleared once I’m done. This is all covered in a good amount of detail on the website. The video in particular is particularly good at showing the sorts of things that Midje is good at.

One problem I ran into immediately is how to integrate it with appengine-magic. The appengine-magic library comes with testing infrastucture to allow you to test your App Engine projects outside a container. By default AEM only includes support for clojure test however with a bit of work it can be made to work with Midje.

I did manage to find a reference to a code snippet on the Midje mailing list but couldn’t get it to work as written. With some small modifications however I managed to get it working.

Firstly we need to define a macro that wraps the setup and teardown work required to get Midje to play nicely with the App Engine testing infrastructure.

(defmacro midje-magic [?form & helpers]
  (let [helper-sym (gensym "helper")]
    `(let [environment# (ApiProxy/getCurrentEnvironment)
           delegate# (ApiProxy/getDelegate)
           ~helper-sym (LocalServiceTestHelper. (into-array LocalServiceTestConfig (local-services-helper)))
           ~@(apply concat
                    (for [helper helpers]
                      (list helper-sym (list helper helper-sym))))]
       (.setUp ~helper-sym)
       ~?form
       (.tearDown ~helper-sym)
       (ApiProxy/setEnvironmentForCurrentThread environment#)
       (ApiProxy/setDelegate delegate#))))

The ?form reference is used to by the background references to insert the test code as it executes. The helpers are optional and allow you to specify appengine-magic test helpers that you wish to be active. With this macro defined we can simply use Midjes normal background declarations to initialize the appengine-magic testing infrastructure. For example:

(background
  (around :facts
          (midje-magic ?form)))

If you wanted to use some helpers you could do something like this:

(background
  (around :facts
          (midje-magic ?form
                       (ae-testing/login "someone@mailhost.com"))))

If you want to get a flavour of what Midje looks like Brian has put together some excellent videos. Links can be found on the Midje wiki:

https://github.com/marick/Midje/wiki

If Midje isn’t your thing there are plenty of altnerative testing frameworks to use. You can find a reasonably up-to-date list at the Clojure Libaries website under the testing category 1.

Magit keybindings

Having decided that Magit is the bee’s knees you’ll probably want to know the keyboard shortcuts.  Here are the most common ones:

  • C-c g Start magit (M-x magit-status)
  • s   Stage file
  • S   Stage all files
  • u   Unstage file
  • c   Commit staged files. C-c C-c after writing commit message or C-c C-k to abort. C-c C-a sdlkfjlkdfj
  • b b   To switch to a branch
  • b m   Rename branch
  • b d   Delete branch
  • b v   List branches (can checkout from resultant screen using RET)
  • P P   Git push
  • f f   Git fetch
  • F F   Git pull
  • TAB   Shows diff of file in the list or expand collapse section. Stage and unstage actually work on bits of the diff as well.
  • i   Ignore file (adds to .gitignore)
  • k   Delete. Deletes untracked file and stashes (on section header it deletes all untracked files). If you’re positioned in a diff for an uncommited file you can also delete just the hunk.
  • l l   Show history
  • l L   Show history in verbose format
  • t t   Make lightweight tag
  • t a   Make annotated tag
  • x   Revert commit history to entered revision
  • z z   Create a stash
  • a   Apply a stash
  • A   Apply the stash and pop it off the stash list
  • z s   Creates a snapshot (the stash gets created but the working tree is not deleted.
  • w   Show how other branches related to the current one
  • m m   Start merging. In the event of conflicts resolve changes using e then stage with s.
  • R   Starts a rebase R c will continue a rebase. Stage resolved conflicts before continuing.

Using magit to do my git commits

Magit is a fantastic Emacs extension for managing git commits.  If you’re an emacs and git user you definitely want to check it out.  If you’re not constantly working inside Emacs though it can be a pain to fire it up, invoke magit then run your magit commands.  I often find myself on the command line wanting to do a quick commit.  To avoid running more steps than absolutely necessary I set up a simple alias:

alias magit=’emacs -nw –eval “(progn (magit-status \”.\”) (delete-other-windows))”‘

This fires up emacs in terminal mode and invokes magit automatically.   Since magit tends to split the frame into two windows I’ve included a command to close the non-magit window by default.

Getting rid of GTK warnings on Emacs 24.1

I recently upgraded to Emacs 24.1 and from the terminal I’ve been getting a ton of errors like so:

Gtk-Message: Failed to load module “canberra-gtk-module”
`menu_proxy_module_load’: emacs: undefined symbol: menu_proxy_module_load

(emacs:17803): Gtk-WARNING **: Failed to load type module: (null)

`menu_proxy_module_load’: emacs: undefined symbol: menu_proxy_module_load

(emacs:17803): Gtk-WARNING **: Failed to load type module: (null)

`menu_proxy_module_load’: emacs: undefined symbol: menu_proxy_module_load

(emacs:17803): Gtk-WARNING **: Failed to load type module: (null)

etc…

Turns out there are a couple of environment variables you can unset in .bashrc to fix this.

export UBUNTU_MENUPROXY=
export GTK_MODULES=

I’ve got no idea what these are for but appears to do the job and I can now start up without seeing a page full of warnings.

Google custom search tips

Google custom search is a very easy way to get a search box on your page.  There are a few things you should be aware of however.

  • Set a good title.  The title is the first thing the user sees for each result.  A list of results with the same title isn’t going to help anyone.
  • Remove pages you don’t want indexed.  One of the easiest ways to do this is via the robots.txt file.
  • Tell Google which bits of the page you don’t want to get summarized in the snippets.  You can do this by adding some special comments: <!– googleoff: snippet –> to tell google you don’t want the following HTML to be included and <!– googleon: snippet –> to switch the normal behaviour back on again.

There are also other switches for turning indexing off and on as well as specifying which links should be followed.  The three points above however should get you decent enough looking search results without having to do too much screwing around.

AI Class 2011

One of the things I did last year was enrol in Stanford’s online AI class. University was almost 20 years ago for me now and I don’t even remember if AI was covered in any great detail at the time. When they announced the free availability of this course I thought (like many others) that it would be a good opportunity. I also enrolled in the machine learning course on the basic track. I wasn’t sure if I’d be able to manage to fit the two courses in but I figured there was no harm in enrolling. As it turned out I didn’t really have the energy for both so the ML class fell by the wayside.

Overall the class was a lot of fun. The subject matter was very broad but not particularly deep. This unfortunately ment that many of the subject areas were covered in a lot less detail than they deserved. Despite this, I think there was still plenty to be learned from the course. The biggest drawback to my mind was the lack of programming exercises. These were apparently originally planned but got cut. The ML-class, which did include programming assignments, seemed to be preferred by the people doing both. I ended up doing some of the material in Clojure to help solidify the concepts.

One thing that I found difficult was getting back into the math. It’s been some time since I did any non-trivial math so there was a bit of catching up to do. This is where having some programming examples would have helped. After 20 years of coding professionally I think much more clearly in programming concepts than in math notation.

This year I plan on doing the natural language processing class. Given some of the things we’ve been doing in the past year at work I wish this had been available a year ago. It is really great to have so many high quality courses on offer for free now.

Xtend

The desire to move beyond Java seems to be growing.  Although Java certainly isn’t going anywhere soon I think Java (the language) has peaked.  The pace of change in the language has been glacially slow over the years and although Oracle are trying to push for a faster release cycle it seems that the pace of change is still too slow.

The vacuum created by this slow rate of change seems to have spawned a glut of new languages.  The newest of these is the Xtend language from Eclipse.  This seems to fill much the same space as Kotlin from Jetbrains.  Both languages seemed to be aimed at reducing the boilerplate of Java without being as complex as Scala.

I can’t help but think this is a niche that Groovy++ seems to be aiming for as well.  There are others too  – Mirah for example.

I think it is kind of sad to see so much fragmentation. Choice is great, but when you start seeing so many nearly identical languages being pushed, it makes you wonder why these guys can’t cooperate on a single effort.

Part of the problem, I think, is that everyone has their own take on what makes the perfect language.  People have their own pet language features and don’t want to give up control.  The result is that everyone loses.  Getting mind share for a new language is hard enough.  When there are dozens competing, it gets that much harder.

Personally I think rather than looking for a language that is Java with nicer syntax we should perhaps be looking beyond a Java.  To something a bit more radical.  I can definitely see the appeal of more incremental changes but  better languages have existed for literally decades and yet remain relatively obscure.  It is time to get a bit more radical and move beyond our comfort zones.

 

Things your mum didn’t tell you about git

The other week we had a rather painful experience with git. My team is currently in the unfortunate position of having to maintain two long running branches. This is not a great idea in general but in our case we don’t have a lot of choice. Our merges have generally been somewhat painful so we resolved to perform them more often. The idea being we break the pain down into smaller more manageable hurts. Last week it was my turn, so I set about merging the code from the branch into master. After running the merge I noticed a lot of conflicts. At the time I thought this was strange considering it wasn’t that long ago that we’d run the previous commit. I fired up merge tool anyway and set about resolving the conflicts then started noticing in conflicts in stuff that should definitely not have been conflicting. At that point I stopped and looked back at the git log to try and see if I could figure out what was going on.

What I found was somewhat disturbing. The last two merges didn’t look like merges at all. A normal merge will have two (or more!) parents (unless git fast forwarded it – a feature which you can turn off on the command line). The last two merges only had a single parent and it looked more like they’d been rebased. I couldn’t understand this because I knew for a fact that the last people to merge into the tree had definitely performed a merge and not a rebase. I did a lot of hunting around at this point to try and figure a way out of this mess and to understand why this had occurred when seemingly we’d done the right things.

Since I had an upcoming release to prepare I didn’t have much time to look into this further so Lee took over and started investigating. After a lot of hunting around he came across a blog post which exactly describes the situation we found ourselves in. What happened was this:

  • Person A starts a merge.
  • Person B commits into the branch you’re merging into.
  • Person A finishes the merge then tries to push it. This fails because the merge is now out-of-date.
  • Person A runs ‘git pull –rebase’ so that he/she can commit the merge.

What Person A has not realised at this point is that the rebase has just trashed the merge commit. In our case we’d done this twice without realising the complete mess we’d just made to our history.

Turns out that if this happens you have to start your merge over from scratch or use an option on the git rebase command called –preserve-merges. This option doesn’t exist in the git pull command so you’ll need issue separate fetch and rebase commands. See the original article for more detail about this.

In the end to clean up we had to abandon the current merge, revert the previous merge mess then rerun the merge. Finally we’re back to a sane(ish) commit history.

I screwed up

My old domain is gone I’m afraid. The email on my domain name provider was set to an old email address and when my domain came up for renewal I never saw the email. As a result my domain lapsed and was picked up my Melbourne IT who were asking for $75/year to get it back. Since there was no way I was about to pay that I decided to just get myself a new domain. Sadly this does mean all my old links are now broken and I’ll be restarting with zero traffic.

It’s been a long time since I’ve really written much on this blog so I may take this as an opportunity to reboot and start writing again. In the near future I’ll probably rename the site to match the domain as well but for the short term I’ll be leaving it as it in case anyone ends up searching for stuff under the old name.

Clojure Web Infrastructure

All the various libraries involved in Clojure web development can be confusing so I created a page to clarify this.  I’m sure there is stuff I’ve missed.  If there’s something you’d like to see added let me know in the comments and I’ll update it.