浏览代码

[Translation] added some unit tests

Fabien Potencier 14 年之前
父节点
当前提交
58bd4acdd1

+ 1 - 2
src/Symfony/Component/Translation/Interval.php

@@ -59,8 +59,7 @@ class Interval
 
             return 
                 ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
-                &&
-                (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
+                && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
             ;
         }
 

+ 24 - 4
src/Symfony/Component/Translation/MessageCatalogue.php

@@ -94,9 +94,7 @@ class MessageCatalogue implements MessageCatalogueInterface
      */
     public function setMessages($messages, $domain = 'messages')
     {
-        if (isset($this->messages[$domain])) {
-            $this->messages[$domain] = array();
-        }
+        $this->messages[$domain] = array();
 
         $this->addMessages($messages, $domain);
     }
@@ -118,6 +116,10 @@ class MessageCatalogue implements MessageCatalogueInterface
      */
     public function addCatalogue(MessageCatalogueInterface $catalogue)
     {
+        if ($catalogue->getLocale() !== $this->locale) {
+            throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale));
+        }
+
         foreach ($catalogue->getMessages() as $domain => $messages) {
             $this->addMessages($messages, $domain);
         }
@@ -127,12 +129,30 @@ class MessageCatalogue implements MessageCatalogueInterface
         }
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        foreach ($catalogue->getDomains() as $domain) {
+            foreach ($catalogue->getMessages($domain) as $id => $translation) {
+                if (false === $this->hasMessage($id, $domain)) {
+                    $this->setMessage($id, $translation, $domain);
+                }
+            }
+        }
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+    }
+
     /**
      * {@inheritdoc}
      */
     public function getResources()
     {
-        return array_unique($this->resources);
+        return array_values(array_unique($this->resources));
     }
 
     /**

+ 12 - 0
src/Symfony/Component/Translation/MessageCatalogueInterface.php

@@ -93,10 +93,22 @@ interface MessageCatalogueInterface
     /**
      * Merges translations from the given Catalogue into the current one.
      *
+     * The two catalogues must have the same locale.
+     *
      * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
      */
     function addCatalogue(MessageCatalogueInterface $catalogue);
 
+    /**
+     * Merges translations from the given Catalogue into the current one
+     * only when the translation does not exist.
+     *
+     * This is used to provide default translations when they do not exist for the current locale.
+     *
+     * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
+     */
+    function addFallbackCatalogue(MessageCatalogueInterface $catalogue);
+
     /**
      * Returns an array of resources loaded to build this collection.
      *

+ 3 - 0
src/Symfony/Component/Translation/PluralizationRules.php

@@ -18,6 +18,7 @@ namespace Symfony\Component\Translation;
  */
 class PluralizationRules
 {
+    // @codeCoverageIgnoreStart
     static protected $rules = array();
 
     /**
@@ -211,4 +212,6 @@ class PluralizationRules
 
         self::$rules[$locale] = $rule;
     }
+
+    // @codeCoverageIgnoreEnd
 }

+ 7 - 15
src/Symfony/Component/Translation/Resource/FileResource.php

@@ -27,13 +27,15 @@ class FileResource implements ResourceInterface
      */
     public function __construct($resource)
     {
+        if (!file_exists($resource)) {
+            throw new \InvalidArgumentException(sprintf('Resource "%s" does not exist.', $resource));
+        }
+
         $this->resource = realpath($resource);
     }
 
     /**
-     * Returns a string representation of the Resource.
-     *
-     * @return string A string representation of the Resource
+     * {@inheritdoc}
      */
     public function __toString()
     {
@@ -41,9 +43,7 @@ class FileResource implements ResourceInterface
     }
 
     /**
-     * Returns the resource tied to this Resource.
-     *
-     * @return mixed The resource
+     * {@inheritdoc}
      */
     public function getResource()
     {
@@ -51,18 +51,10 @@ class FileResource implements ResourceInterface
     }
 
     /**
-     * Returns true if the resource has not been updated since the given timestamp.
-     *
-     * @param timestamp $timestamp The last time the resource was loaded
-     *
-     * @return Boolean true if the resource has not been updated, false otherwise
+     * {@inheritdoc}
      */
     public function isUptodate($timestamp)
     {
-        if (!file_exists($this->resource)) {
-            return false;
-        }
-
         return filemtime($this->resource) < $timestamp;
     }
 }

+ 7 - 18
src/Symfony/Component/Translation/Translator.php

@@ -93,10 +93,8 @@ class Translator implements TranslatorInterface
      */
     public function setFallbackLocale($locale)
     {
-        if (null !== $this->fallbackLocale) {
-            // needed as the fallback locale is used to fill-in non-yet translated messages
-            $this->catalogues = array();
-        }
+        // needed as the fallback locale is used to fill-in non-yet translated messages
+        $this->catalogues = array();
 
         $this->fallbackLocale = $locale;
     }
@@ -135,10 +133,6 @@ class Translator implements TranslatorInterface
 
     protected function loadCatalogue($locale)
     {
-        if (isset($this->catalogues[$locale])) {
-            return;
-        }
-
         $this->catalogues[$locale] = new MessageCatalogue($locale);
         if (!isset($this->resources[$locale])) {
             return;
@@ -162,19 +156,14 @@ class Translator implements TranslatorInterface
             $fallback = $this->fallbackLocale;
         }
 
+        if (!$fallback) {
+            return;
+        }
+
         if (!isset($this->catalogues[$fallback])) {
             $this->loadCatalogue($fallback);
         }
 
-        foreach ($this->catalogues[$fallback]->getResources() as $resource) {
-            $this->catalogues[$locale]->addResource($resource);
-        }
-        foreach ($this->catalogues[$fallback]->getDomains() as $domain) {
-            foreach ($this->catalogues[$fallback]->getMessages($domain) as $id => $translation) {
-                if (false === $this->catalogues[$locale]->hasMessage($id, $domain)) {
-                    $this->catalogues[$locale]->setMessage($id, $translation, $domain);
-                }
-            }
-        }
+        $this->catalogues[$locale]->addFallbackCatalogue($this->catalogues[$fallback]);
     }
 }

+ 61 - 0
tests/Symfony/Tests/Component/Translation/IdentityTranslatorTest.php

@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation;
+
+use Symfony\Component\Translation\IdentityTranslator;
+use Symfony\Component\Translation\MessageSelector;
+
+class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getTransTests
+     */
+    public function testTrans($expected, $id, $parameters)
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoice($expected, $id, $number, $parameters)
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+    }
+
+    // noop
+    public function testGetSetLocale()
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+        $translator->setLocale('en');
+        $translator->getLocale();
+    }
+
+    public function getTransTests()
+    {
+        return array(
+            array('Symfony2 is great!', 'Symfony2 is great!', array()),
+            array('Symfony2 is awesome!', 'Symfony2 is %what%!', array('%what%' => 'awesome')),
+        );
+    }
+
+    public function getTransChoiceTests()
+    {
+        return array(
+            array('There is 10 apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 10, array('%count%' => 10)),
+        );
+    }
+}

+ 29 - 0
tests/Symfony/Tests/Component/Translation/Loader/PhpFileLoaderTest.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Loader\PhpFileLoader;
+use Symfony\Component\Translation\Resource\FileResource;
+
+class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new PhpFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.php';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->getMessages('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+}

+ 47 - 0
tests/Symfony/Tests/Component/Translation/Loader/XliffFileLoaderTest.php

@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Loader\XliffFileLoader;
+use Symfony\Component\Translation\Resource\FileResource;
+
+class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new XliffFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.xliff';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->getMessages('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException Exception
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException Exception
+     */
+    public function testLoadResourceDoesNotValidate()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/non-valid.xliff', 'en', 'domain1');
+    }
+}

+ 149 - 0
tests/Symfony/Tests/Component/Translation/MessageCatalogTest.php

@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+class MessageCatalogueTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLocale()
+    {
+        $catalogue = new MessageCatalogue('en');
+
+        $this->assertEquals('en', $catalogue->getLocale());
+    }
+
+    public function testGetDomains()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array()));
+
+        $this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains());
+    }
+
+    public function testGetMessages()
+    {
+        $catalogue = new MessageCatalogue('en', $messages = array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+        $this->assertEquals(array('foo' => 'foo'), $catalogue->getMessages('domain1'));
+        $this->assertEquals(array(), $catalogue->getMessages('domain88'));
+        $this->assertEquals($messages, $catalogue->getMessages());
+    }
+
+    public function testHasMessage()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+        $this->assertTrue($catalogue->hasMessage('foo', 'domain1'));
+        $this->assertFalse($catalogue->hasMessage('bar', 'domain1'));
+        $this->assertFalse($catalogue->hasMessage('foo', 'domain88'));
+    }
+
+    public function testGetSetMessage()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->setMessage('foo1', 'foo1', 'domain1');
+
+        $this->assertEquals('foo', $catalogue->getMessage('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->getMessage('foo1', 'domain1'));
+    }
+
+    public function testAddMessages()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->addMessages(array('foo1' => 'foo1'), 'domain1');
+
+        $this->assertEquals('foo', $catalogue->getMessage('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->getMessage('foo1', 'domain1'));
+
+        $catalogue->addMessages(array('foo' => 'bar'), 'domain1');
+        $this->assertEquals('bar', $catalogue->getMessage('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->getMessage('foo1', 'domain1'));
+
+        $catalogue->addMessages(array('foo' => 'bar'), 'domain88');
+        $this->assertEquals('bar', $catalogue->getMessage('foo', 'domain88'));
+    }
+
+    public function testSetMessages()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->setMessages($messages = array('foo1' => 'foo1'), 'domain1');
+
+        $this->assertEquals($messages, $catalogue->getMessages('domain1'));
+    }
+
+    public function testAddCatalogue()
+    {
+        $r = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+        $r1 = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->addResource($r);
+
+        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1')));
+        $catalogue1->addResource($r1);
+
+        $catalogue->addCatalogue($catalogue1);
+
+        $this->assertEquals('foo', $catalogue->getMessage('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->getMessage('foo1', 'domain1'));
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+
+    public function testAddFallbackCatalogue()
+    {
+        $r = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+        $r1 = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+        $catalogue = new MessageCatalogue('en_US', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->addResource($r);
+
+        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo' => 'bar', 'foo1' => 'foo1')));
+        $catalogue1->addResource($r1);
+
+        $catalogue->addFallbackCatalogue($catalogue1);
+
+        $this->assertEquals('foo', $catalogue->getMessage('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->getMessage('foo1', 'domain1'));
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException LogicException
+     */
+    public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->addCatalogue(new MessageCatalogue('fr', array()));
+    }
+
+    public function testGetAddResource()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $r = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+        $catalogue->addResource($r);
+        $catalogue->addResource($r);
+        $r1 = $this->getMock('Symfony\Component\Translation\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+        $catalogue->addResource($r1);
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+}

+ 58 - 0
tests/Symfony/Tests/Component/Translation/MessageSelectorTest.php

@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation;
+
+use Symfony\Component\Translation\MessageSelector;
+
+class MessageSelectorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getChooseTests
+     */
+    public function testChoose($expected, $id, $number)
+    {
+        $selector = new MessageSelector();
+
+        $this->assertEquals($expected, $selector->choose($id, $number, 'en'));
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testChooseWhenNoEnoughChoices()
+    {
+        $selector = new MessageSelector();
+
+        $selector->choose('foo', 10, 'en');
+    }
+
+    public function getChooseTests()
+    {
+        return array(
+            array('There is no apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 0),
+            array('There is one apple', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 1),
+            array('There is %count% apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 10),
+
+            array('There is %count% apples', 'There is one apple|There is %count% apples', 0),
+            array('There is one apple', 'There is one apple|There is %count% apples', 1),
+            array('There is %count% apples', 'There is one apple|There is %count% apples', 10),
+
+            array('There is %count% apples', 'one: There is one apple|more: There is %count% apples', 0),
+            array('There is one apple', 'one: There is one apple|more: There is %count% apples', 1),
+            array('There is %count% apples', 'one: There is one apple|more: There is %count% apples', 10),
+
+            array('There is no apples', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 0),
+            array('There is one apple', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 1),
+            array('There is %count% apples', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 10),
+        );
+    }
+}

+ 48 - 0
tests/Symfony/Tests/Component/Translation/Resource/FileResourceTest.php

@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Translation\Resource;
+
+use Symfony\Component\Translation\Resource\FileResource;
+
+class FileResourceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructor()
+    {
+        $resource = new FileResource(__DIR__.'/../fixtures/foobar');
+    }
+
+    public function testMagicToString()
+    {
+        $resource = new FileResource(__DIR__.'/../fixtures/resources.php');
+
+        $this->assertEquals(realpath(__DIR__.'/../fixtures/resources.php'), (string) $resource);
+    }
+
+    public function testGetResource()
+    {
+        $resource = new FileResource(__DIR__.'/../fixtures/resources.php');
+
+        $this->assertEquals(realpath(__DIR__.'/../fixtures/resources.php'), $resource->getResource());
+    }
+
+    public function testIsUptodate()
+    {
+        $r = __DIR__.'/../fixtures/resources.php';
+        $resource = new FileResource($r);
+
+        $this->assertFalse($resource->isUptodate(filemtime($r) - 100));
+        $this->assertTrue($resource->isUptodate(filemtime($r) + 100));
+    }
+}

+ 45 - 0
tests/Symfony/Tests/Component/Translation/TranslatorTest.php

@@ -17,6 +17,51 @@ use Symfony\Component\Translation\Loader\ArrayLoader;
 
 class TranslatorTest extends \PHPUnit_Framework_TestCase
 {
+    public function testSetGetLocale()
+    {
+        $translator = new Translator('en', new MessageSelector());
+
+        $this->assertEquals('en', $translator->getLocale());
+
+        $translator->setLocale('fr');
+        $this->assertEquals('fr', $translator->getLocale());
+    }
+
+    public function testSetFallbackLocale()
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+        $translator->addResource('array', array('bar' => 'foobar'), 'fr');
+
+        // force catalogue loading
+        $translator->trans('bar');
+
+        $translator->setFallbackLocale('fr');
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    public function testTransWithFallbackLocale()
+    {
+        $translator = new Translator('en_US', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
+        $translator->addResource('array', array('bar' => 'foobar'), 'en');
+
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testWhenAResourceHasNoRegisteredLoader()
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+        $translator->trans('foo');
+    }
+
     /**
      * @dataProvider getTransTests
      */

+ 11 - 0
tests/Symfony/Tests/Component/Translation/fixtures/non-valid.xliff

@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+    <file source-language="en" datatype="plaintext" original="file.ext">
+        <body>
+            <trans-unit>
+                <source>foo</source>
+                <target>bar</target>
+            </trans-unit>
+        </body>
+    </file>
+</xliff>

+ 5 - 0
tests/Symfony/Tests/Component/Translation/fixtures/resources.php

@@ -0,0 +1,5 @@
+<?php
+
+return array(
+    'foo' => 'bar',
+);

+ 11 - 0
tests/Symfony/Tests/Component/Translation/fixtures/resources.xliff

@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+    <file source-language="en" datatype="plaintext" original="file.ext">
+        <body>
+            <trans-unit id="1">
+                <source>foo</source>
+                <target>bar</target>
+            </trans-unit>
+        </body>
+    </file>
+</xliff>