{"id":3057,"date":"2015-11-05T00:18:08","date_gmt":"2015-11-04T22:18:08","guid":{"rendered":"http:\/\/humanoids.be\/log\/?p=3057"},"modified":"2015-11-05T00:18:55","modified_gmt":"2015-11-04T22:18:55","slug":"checking-code-coverage-of-add-on-sdk-extensions","status":"publish","type":"post","link":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/","title":{"rendered":"Checking Code Coverage of Add-on SDK Extensions"},"content":{"rendered":"<p>Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write unit tests for, because 100% coverage doesn&#8217;t exist. And sometimes you can&#8217;t cover all code. That&#8217;s why normally you are happy, if the coverage is above a certain thresh hold, but having a higher coverage is always ok<\/p>\n<p>One of the typical coverage tools for CommonJS based code is <em><a href=\"https:\/\/www.npmjs.com\/package\/istanbul\">istanbul<\/a><\/em>. Sadly it doesn&#8217;t work just out of the box, because the coverage calculations and tests aren&#8217;t run in the same JS engine. The tests run in Firefox and the calculations happen outside in NodeJS.<!--more--><\/p>\n<p>By default Istanbul uses a global variable to store the coverage information. The problem begins with the CommonJS environment of the Add-on SDK not having a global environment. To work around that, I&#8217;ve made <a href=\"https:\/\/github.com\/freaktechnik\/istanbul-jpm\/blob\/master\/global.js\">a module<\/a> that exports an object which istanbul then treats as its global object. But to do that, the <em>Instrumenter<\/em>, the thing that makes your code inspectable during unit tests, has to be modified to use that module instead of the Node global. Luckily this is just a modification of one line in a function in the prototype of the Instrumenter. This happens in the <a href=\"https:\/\/github.com\/freaktechnik\/istanbul-jpm\/blob\/master\/index.js\">main module<\/a> of the <em><a href=\"https:\/\/www.npmjs.com\/package\/istanbul-jpm\">istanbul-jpm<\/a><\/em> package, which I created.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/* The second item in the array differs from the normal\r\n * Instrumenter, everything else is the same. *\/\r\ncode = &#x5B;\r\n    &quot;%STRICT%&quot;,\r\n    &quot;var %VAR% = require('istanbul-jpm\/global').global;&quot;,\r\n    &quot;if (!%VAR%.%GLOBAL%) { %VAR%.%GLOBAL% = {}; }&quot;,\r\n    &quot;%VAR% = %VAR%.%GLOBAL%;&quot;,\r\n    &quot;if (!(%VAR%&#x5B;'%FILE%'])) {&quot;,\r\n    &quot;   %VAR%&#x5B;'%FILE%'] = %OBJECT%;&quot;,\r\n    &quot;}&quot;,\r\n    &quot;%VAR% = %VAR%&#x5B;'%FILE%'];&quot;\r\n]\r\n<\/pre>\n<p>Having a custom module providing the &#8220;global&#8221; scope also makes bridging the gap between Firefox and Node really easy. It just serializes the &#8220;global&#8221; object when the extension is unloaded (after all unit tests are done) and writes it to disk. Funnily enough the module is called <em>global<\/em>. There is a module for node that then reads and parses that file called <em>global-node<\/em>.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/* Loading the collected coverage data into the node\r\n * environment. *\/\r\nglobal.__coverage__ = require(&quot;istanbul-jpm\/global-node&quot;).global.__coverage__;\r\n<\/pre>\n<p>Only the <em>global.js<\/em> from the istanbul-jpm package is needed during unit tests, everything else can safely be .jpmignored. Sadly you have to do that yourself, since JPM doesn&#8217;t respect the <em>.jpmignore<\/em> files from extensions.<\/p>\n<p>And that&#8217;s all the extra magic needed. The rest is magic that needs to happen whenever you collect coverage data. But because generating coverage statistics is quite complicated I&#8217;ll explain the other steps too:<\/p>\n<p>Before the unit tests are ran, the Instrumenter adds the tracking logic to your modules (normally everything in your <em>lib<\/em> folder and maybe in your root). I haven&#8217;t bothered to figure out a way to do coverage analysis for content scripts, by the way.<\/p>\n<p>But for coverage data to be collected the modules generated by the Instrumenter have to be loaded in the unit tests and not the normal modules. Common practice is to create a require-helper module, that checks an environment variable and either loads the module from its actual location or redirects it to the instrumented version.<\/p>\n<p>An example implementation for instrumented modules being in the <em>\/coverage\/instrument\/lib\/<\/em> folder, the following code does exactly what is described in the previous paragraph. If the environment variable <code>JPM_MEASURING_COVERAGE<\/code> is set, it redirects to the instrumented versions.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nconst system = require(&quot;sdk\/system&quot;);\r\n\r\nmodule.exports = function (path) {\r\n    if(system.env.JPM_MEASURING_COVERAGE)\r\n        return require('..\/coverage\/instrument\/test\/' + path);\r\n    else\r\n        return require(path);\r\n};\r\n<\/pre>\n<p>After the unit tests a report has to be generated. This can have many forms, and really depends on what you want to do with coverage statistics.<\/p>\n<p>I use grunt to manage all of this, a bootsrapped <em>Gruntfile.js<\/em> can be found in the <a href=\"https:\/\/www.npmjs.com\/package\/istanbul-jpm#example-usage-with-grunt-istanbul\"><em>README,md<\/em> of the istanbul-jpm module<\/a>. There is also the monstrosity, that is the <a href=\"https:\/\/github.com\/freaktechnik\/justintv-stream-notifications\/blob\/master\/Gruntfile.js\"><em>Gruntfile.js<\/em> of my jtvn extension<\/a>.<\/p>\n<p>The <a href=\"https:\/\/www.npmjs.com\/package\/istanbul-jpm\">istanbul-jpm<\/a> module helps close the gap between the normal Node environment and JPM tests for coverage analysis with istanbul. It&#8217;s pretty young, but there&#8217;s not much that can go wrong. Give it a try!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write unit tests for, because 100% coverage doesn&#8217;t exist. And sometimes you can&#8217;t cover all code. That&#8217;s why normally you are happy, if the coverage is above a &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Checking Code Coverage of Add-on SDK Extensions&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":3069,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[616],"tags":[707,711,706,93,660,669,709,708,710],"class_list":["post-3057","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sdk-extensions","tag-coverage","tag-instrument","tag-istanbul","tag-jetpack","tag-jpm","tag-test","tag-unit","tag-unit-test","tag-xpi"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog<\/title>\n<meta name=\"description\" content=\"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog\" \/>\n<meta property=\"og:description\" content=\"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write\" \/>\n<meta property=\"og:url\" content=\"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/\" \/>\n<meta property=\"og:site_name\" content=\"Humanoids beLog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/humanoidsbelog\" \/>\n<meta property=\"article:published_time\" content=\"2015-11-04T22:18:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-11-04T22:18:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1007\" \/>\n\t<meta property=\"og:image:height\" content=\"573\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Martin Giger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@freaktechnik\" \/>\n<meta name=\"twitter:site\" content=\"@freaktechnik\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Martin Giger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/\"},\"author\":{\"name\":\"Martin Giger\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/#\\\/schema\\\/person\\\/a58850edf3908fc1b0987aedfb9a080d\"},\"headline\":\"Checking Code Coverage of Add-on SDK Extensions\",\"datePublished\":\"2015-11-04T22:18:08+00:00\",\"dateModified\":\"2015-11-04T22:18:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/\"},\"wordCount\":713,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/humanoids.be\\\/log\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/coverage.png\",\"keywords\":[\"coverage\",\"instrument\",\"istanbul\",\"jetpack\",\"jpm\",\"test\",\"unit\",\"unit test\",\"xpi\"],\"articleSection\":[\"Add-on SDK\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/\",\"url\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/\",\"name\":\"Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/humanoids.be\\\/log\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/coverage.png\",\"datePublished\":\"2015-11-04T22:18:08+00:00\",\"dateModified\":\"2015-11-04T22:18:55+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/#\\\/schema\\\/person\\\/a58850edf3908fc1b0987aedfb9a080d\"},\"description\":\"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/humanoids.be\\\/log\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/coverage.png\",\"contentUrl\":\"https:\\\/\\\/humanoids.be\\\/log\\\/wp-content\\\/uploads\\\/2015\\\/11\\\/coverage.png\",\"width\":1007,\"height\":573},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/2015\\\/11\\\/checking-code-coverage-of-add-on-sdk-extensions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/humanoids.be\\\/log\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Checking Code Coverage of Add-on SDK Extensions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/#website\",\"url\":\"https:\\\/\\\/humanoids.be\\\/log\\\/\",\"name\":\"Humanoids beLog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/humanoids.be\\\/log\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/humanoids.be\\\/log\\\/#\\\/schema\\\/person\\\/a58850edf3908fc1b0987aedfb9a080d\",\"name\":\"Martin Giger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg\",\"caption\":\"Martin Giger\"},\"description\":\"openpgp4fpr:89346D522A2C190EEB959F52AE530058EFE7FD60\",\"sameAs\":[\"http:\\\/\\\/humanoids.be\\\/\"],\"url\":\"https:\\\/\\\/humanoids.be\\\/log\\\/author\\\/humanoid\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog","description":"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/","og_locale":"en_US","og_type":"article","og_title":"Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog","og_description":"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write","og_url":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/","og_site_name":"Humanoids beLog","article_publisher":"https:\/\/www.facebook.com\/humanoidsbelog","article_published_time":"2015-11-04T22:18:08+00:00","article_modified_time":"2015-11-04T22:18:55+00:00","og_image":[{"width":1007,"height":573,"url":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","type":"image\/png"}],"author":"Martin Giger","twitter_card":"summary_large_image","twitter_creator":"@freaktechnik","twitter_site":"@freaktechnik","twitter_misc":{"Written by":"Martin Giger","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#article","isPartOf":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/"},"author":{"name":"Martin Giger","@id":"https:\/\/humanoids.be\/log\/#\/schema\/person\/a58850edf3908fc1b0987aedfb9a080d"},"headline":"Checking Code Coverage of Add-on SDK Extensions","datePublished":"2015-11-04T22:18:08+00:00","dateModified":"2015-11-04T22:18:55+00:00","mainEntityOfPage":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/"},"wordCount":713,"commentCount":0,"image":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#primaryimage"},"thumbnailUrl":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","keywords":["coverage","instrument","istanbul","jetpack","jpm","test","unit","unit test","xpi"],"articleSection":["Add-on SDK"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/","url":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/","name":"Checking Code Coverage of Add-on SDK Extensions - Humanoids beLog","isPartOf":{"@id":"https:\/\/humanoids.be\/log\/#website"},"primaryImageOfPage":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#primaryimage"},"image":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#primaryimage"},"thumbnailUrl":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","datePublished":"2015-11-04T22:18:08+00:00","dateModified":"2015-11-04T22:18:55+00:00","author":{"@id":"https:\/\/humanoids.be\/log\/#\/schema\/person\/a58850edf3908fc1b0987aedfb9a080d"},"description":"Code coverage statistics are very useful. They tell you how much of your code never gets executed during the unit tests. So you always know what to write","breadcrumb":{"@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#primaryimage","url":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","contentUrl":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","width":1007,"height":573},{"@type":"BreadcrumbList","@id":"https:\/\/humanoids.be\/log\/2015\/11\/checking-code-coverage-of-add-on-sdk-extensions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/humanoids.be\/log\/"},{"@type":"ListItem","position":2,"name":"Checking Code Coverage of Add-on SDK Extensions"}]},{"@type":"WebSite","@id":"https:\/\/humanoids.be\/log\/#website","url":"https:\/\/humanoids.be\/log\/","name":"Humanoids beLog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/humanoids.be\/log\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/humanoids.be\/log\/#\/schema\/person\/a58850edf3908fc1b0987aedfb9a080d","name":"Martin Giger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8766da02c6809c8ca3142c0c75bbfd454a6d1120dc01fede05d0beffedb6dd40?s=96&d=mm&r=pg","caption":"Martin Giger"},"description":"openpgp4fpr:89346D522A2C190EEB959F52AE530058EFE7FD60","sameAs":["http:\/\/humanoids.be\/"],"url":"https:\/\/humanoids.be\/log\/author\/humanoid\/"}]}},"jetpack_featured_media_url":"https:\/\/humanoids.be\/log\/wp-content\/uploads\/2015\/11\/coverage.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/posts\/3057","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/comments?post=3057"}],"version-history":[{"count":12,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/posts\/3057\/revisions"}],"predecessor-version":[{"id":3071,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/posts\/3057\/revisions\/3071"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/media\/3069"}],"wp:attachment":[{"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/media?parent=3057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/categories?post=3057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/humanoids.be\/log\/wp-json\/wp\/v2\/tags?post=3057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}