<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>meier-online</title>
	<atom:link href="http://meier-online.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://meier-online.com</link>
	<description>Der Blog von Karsten Meier</description>
	<lastBuildDate>Sun, 09 Oct 2011 13:27:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>(Deutsch) LwUIT 1.5 erste Erfahrungen</title>
		<link>http://meier-online.com/en/2011/10/lwuit-1-5/</link>
		<comments>http://meier-online.com/en/2011/10/lwuit-1-5/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 13:21:06 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JME]]></category>
		<category><![CDATA[LWUIT]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=794</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2011/10/lwuit-1-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Deutsch) Ilias Skins</title>
		<link>http://meier-online.com/en/2011/07/ilias-skins/</link>
		<comments>http://meier-online.com/en/2011/07/ilias-skins/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 11:39:43 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=744</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2011/07/ilias-skins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Deutsch) Eins plus Zwei</title>
		<link>http://meier-online.com/en/2010/12/one-plus_two/</link>
		<comments>http://meier-online.com/en/2010/12/one-plus_two/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 17:42:11 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Traps]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Typumwandlung]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=726</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2010/12/one-plus_two/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multilingual Websites with Ruby on Rails (3)</title>
		<link>http://meier-online.com/en/2010/01/mehrsprachige-webseiten-mit-ruby-on-rails-3/</link>
		<comments>http://meier-online.com/en/2010/01/mehrsprachige-webseiten-mit-ruby-on-rails-3/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 10:02:16 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[multilingualism]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=656</guid>
		<description><![CDATA[Part 3 &#8211; Quality Assurence Texte gehören zu den Teilen einer Anwendung, die häufig geändert werden. Wenn dann noch externe Übersetzer im Spiel sind, kann es leicht zu fehlenden Übersetzungen kommen Wir möchten deshalb automatisch testen, dass es zu allen Texten in Sprache A auch Übersetzungen in Sprache B vorhanden sind. Ein solcher Test allein [...]]]></description>
			<content:encoded><![CDATA[<p>Part 3 &#8211; Quality Assurence</p>
<p>Texte gehören zu den Teilen einer Anwendung, die häufig geändert werden. Wenn dann noch externe Übersetzer im Spiel sind, kann es leicht zu fehlenden Übersetzungen kommen</p>
<p>Wir möchten deshalb automatisch testen, dass es zu allen Texten in Sprache A auch Übersetzungen in Sprache B vorhanden sind. Ein solcher Test allein hilft schon sehr, und sollte ja nicht so schwierig sein.</p>
<p>Leider gibt es dabei eine Überraschung: in der Internationalisierung-API findet sich zur Zeit (Rails 2.3.5) keine Möglichkeit, alle Schlüssel aufzuzählen (sprich iterieren). Man muss also offenbar die Yaml-Dateien selbst einlesen, um an alle Schlüssel zu kommen. Unserer Test ist dabei leider abhängig von der konkreten Art der Datenhaltung.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">texts_hash = <span style="color:#CC00FF; font-weight:bold;">YAML</span>::<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'config/locales/de.yml'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Wie haben nun einen rekursiven Hash. Um alle Schlüssel zu überprüfen, extrahieren wie sie mit einer gesonderten Funktion. Diese Funktion ist einfach rekursiv aufgebaut.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> deep_hash_key<span style="color:#006600; font-weight:bold;">&#40;</span>hash, prefix<span style="color:#006600; font-weight:bold;">&#41;</span>
  hash.<span style="color:#9900CC;">keys</span>.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>key2<span style="color:#006600; font-weight:bold;">|</span>
    val = hash<span style="color:#006600; font-weight:bold;">&#91;</span>key2<span style="color:#006600; font-weight:bold;">&#93;</span>
    newprefix = prefix.<span style="color:#0000FF; font-weight:bold;">nil</span>? ? key2 : <span style="color:#996600;">&quot;#{prefix}.#{key2}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> val.<span style="color:#9900CC;">is_a</span>? <span style="color:#CC00FF; font-weight:bold;">Hash</span>
     deep_hash_key<span style="color:#006600; font-weight:bold;">&#40;</span>val, newprefix<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      newprefix
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wollen wir jetzt die Übersetzungen für alle Schlüssel prüfen lauert die Zweite Falle: Wenn die Übersetzung eine Variableninterpolation enthält, erhalten wir einen Fehler beim Aufrufen der translate() Methode ohne den passenden Hash. Offenbar liefert uns die API auch keinen Zugriff auf den String ohne Interpolierung. Da uns in diesen Test nur die Existenz einer Übersetzung interessiert, und nicht ihr konkreter Wert, fangen wir die Exception &#8220;MissingInterpolationArgument&#8221; einfach auf.</p>
<p>Für eine deutsche Anwendung mit Übersetzungen in Englisch und Französisch sieht dann der Test so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> test_all_texts_should_exists
  texts_hash = <span style="color:#CC00FF; font-weight:bold;">YAML</span>::<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">IO</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'config/locales/de.yml'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  de_keys = deep_hash_key<span style="color:#006600; font-weight:bold;">&#40;</span>texts_hash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'de'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">flatten</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> lang <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'de'</span>, <span style="color:#996600;">'fr'</span>, <span style="color:#996600;">'en'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    I18n::locale = lang
    <span style="color:#9966CC; font-weight:bold;">for</span> key <span style="color:#9966CC; font-weight:bold;">in</span> de_keys
      <span style="color:#9966CC; font-weight:bold;">begin</span>
        val = I18n.<span style="color:#9900CC;">translate</span><span style="color:#006600; font-weight:bold;">&#40;</span>key, <span style="color:#ff3333; font-weight:bold;">:default</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#0000FF; font-weight:bold;">nil</span>, :<span style="color:#CC0066; font-weight:bold;">raise</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">I18n::MissingTranslationData</span>
        val = <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">I18n::MissingInterpolationArgument</span>
        val = <span style="color:#0000FF; font-weight:bold;">true</span>  <span style="color:#008000; font-style:italic;"># there was a value, only an argument is missing</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      assert_not_nil<span style="color:#006600; font-weight:bold;">&#40;</span>val, <span style="color:#996600;">&quot;key missing for locale #{lang}: #{key}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wenn jetzt eine Übersetzung fehlt, liefert der Test eine Fehlermeldung der Art:</p>
<pre>
test_all_texts_should_exists(LocalisationTest): key missing for locale en: users.edit.title</pre>
<p>Die fehlende Übersetzung können wir dann ergänzen, bevor wir eine neue Version der Anwendung veröffentlichen.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2010/01/mehrsprachige-webseiten-mit-ruby-on-rails-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Deutsch) Classics reloaded: Das Assert-Makro von C</title>
		<link>http://meier-online.com/en/2009/09/assert/</link>
		<comments>http://meier-online.com/en/2009/09/assert/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 14:41:43 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Assert]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[quality assurance]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=618</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2009/09/assert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Deutsch) Rotierende Reklametafel mit jQuery</title>
		<link>http://meier-online.com/en/2009/08/rolling-billboard-jquery/</link>
		<comments>http://meier-online.com/en/2009/08/rolling-billboard-jquery/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 17:15:05 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Reklametafel]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=584</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2009/08/rolling-billboard-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(Deutsch) Google Technology User Group Hamburg</title>
		<link>http://meier-online.com/en/2009/06/gtug-hamburg-appengine-mapplet/</link>
		<comments>http://meier-online.com/en/2009/06/gtug-hamburg-appengine-mapplet/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 15:15:54 +0000</pubDate>
		<dc:creator>meier</dc:creator>
				<category><![CDATA[IT-Scene]]></category>
		<category><![CDATA[AppEngine]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Mapplet]]></category>

		<guid isPermaLink="false">http://meier-online.com/?p=504</guid>
		<description><![CDATA[Sorry, this entry is only available in Deutsch.]]></description>
			<content:encoded><![CDATA[<p>Sorry, this entry is only available in <a href="http://meier-online.com/feed/">Deutsch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://meier-online.com/en/2009/06/gtug-hamburg-appengine-mapplet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

