Passed
Push — master ( 56b970...3daa8a )
by Christophe
01:56
created

CompareCommandTest   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 134
dl 0
loc 218
rs 10
c 0
b 0
f 0
wmc 8

7 Methods

Rating   Name   Duplication   Size   Complexity  
A testExecute() 0 16 2
B provideCommandData() 0 104 1
A testFailsForNonExistentWhitelist() 0 15 1
A testSucceedWithWhitelistedMessagesAndMissingMessage() 0 19 1
A testWhitelistIsDomainBased() 0 16 1
A testFailsForInvalidWhitelist() 0 15 1
A testSucceedWithWhitelistedMessages() 0 13 1
1
<?php
2
3
namespace Incenteev\TranslationCheckerBundle\Tests\Command;
4
5
use Incenteev\TranslationCheckerBundle\Command\CompareCommand;
6
use PHPUnit\Framework\TestCase;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Console\Tester\CommandTester;
9
use Symfony\Component\Translation\MessageCatalogue;
10
11
class CompareCommandTest extends TestCase
12
{
13
    /**
14
     * @dataProvider provideCommandData
15
     */
16
    public function testExecute($sourceLocale, array $sourceMessages, $comparedLocale, array $comparedMessages, array $input, $expectedExitCode, $expectedMessages, $verbosity = OutputInterface::VERBOSITY_NORMAL)
17
    {
18
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
19
20
        $loader->getCatalogue($sourceLocale)->willReturn(new MessageCatalogue($sourceLocale, $sourceMessages));
21
        $loader->getCatalogue($comparedLocale)->willReturn(new MessageCatalogue($comparedLocale, $comparedMessages));
22
23
        $command = new CompareCommand($loader->reveal());
24
25
        $tester = new CommandTester($command);
26
        $exitCode = $tester->execute($input, array('decorated' => false, 'verbosity' => $verbosity));
27
28
        $this->assertEquals($expectedExitCode, $exitCode);
29
30
        foreach ((array) $expectedMessages as $message) {
31
            $this->assertContains($message, $tester->getDisplay());
32
        }
33
    }
34
35
    public function provideCommandData()
36
    {
37
        return array(
38
            'sync with en' => array(
39
                'en',
40
                array('messages' => array('foo' => 'bar')),
41
                'fr',
42
                array('messages' => array('foo' => 'baz')),
43
                array('locale' => 'fr'),
44
                0,
45
                'The fr catalogue is in sync with the en one.',
46
            ),
47
            'sync with en explicit' => array(
48
                'en',
49
                array('messages' => array('foo' => 'bar'), 'test' => array('me' => 'Me')),
50
                'fr',
51
                array('messages' => array('foo' => 'baz'), 'test' => array('me' => 'Moi')),
52
                array('locale' => 'fr', 'source' => 'en'),
53
                0,
54
                'The fr catalogue is in sync with the en one.',
55
                OutputInterface::VERBOSITY_VERBOSE,
56
            ),
57
            'missing message' => array(
58
                'en',
59
                array('messages' => array('foo' => 'bar')),
60
                'fr',
61
                array('messages' => array()),
62
                array('locale' => 'fr'),
63
                1,
64
                '1 messages are missing in the messages domain',
65
            ),
66
            'missing message verbose' => array(
67
                'en',
68
                array('messages' => array('foo' => 'bar')),
69
                'fr',
70
                array('messages' => array()),
71
                array('locale' => 'fr'),
72
                1,
73
                array('1 messages are missing in the messages domain', '    foo'),
74
                OutputInterface::VERBOSITY_VERBOSE,
75
            ),
76
            'obsolete message' => array(
77
                'en',
78
                array('messages' => array('foo' => 'bar')),
79
                'fr',
80
                array('messages' => array('foo' => 'bar', 'bar' => 'baz', 'old' => 'one')),
81
                array('locale' => 'fr'),
82
                1,
83
                '2 messages are obsolete in the messages domain',
84
            ),
85
            'obsolete message verbose' => array(
86
                'en',
87
                array('messages' => array('foo' => 'bar')),
88
                'fr',
89
                array('messages' => array('foo' => 'bar', 'bar' => 'baz', 'old.key' => 'one')),
90
                array('locale' => 'fr'),
91
                1,
92
                array('2 messages are obsolete in the messages domain', '    bar', '    old.key'),
93
                OutputInterface::VERBOSITY_VERBOSE,
94
            ),
95
            'missing and obsolete message' => array(
96
                'en',
97
                array('messages' => array('foo' => 'bar'), 'test' => array('hello' => 'world')),
98
                'fr',
99
                array('messages' => array('foo' => 'bar', 'bar' => 'baz', 'old' => 'one')),
100
                array('locale' => 'fr'),
101
                1,
102
                array('2 messages are obsolete in the messages domain', '1 messages are missing in the test domain'),
103
            ),
104
            'domain restriction sync' => array(
105
                'en',
106
                array('messages' => array('foo' => 'bar'), 'test' => array('foo' => 'bar')),
107
                'fr',
108
                array('messages' => array('foo' => 'baz')),
109
                array('locale' => 'fr', '--domain' => array('messages', 'other')),
110
                0,
111
                array('The fr catalogue is in sync with the en one.', 'Checking the domains messages'),
112
            ),
113
            'domain restriction missing' => array(
114
                'en',
115
                array('messages' => array('foo' => 'bar'), 'test' => array('foo' => 'bar')),
116
                'fr',
117
                array('messages' => array('foo' => 'baz'), 'other' => array('hello' => 'world')),
118
                array('locale' => 'fr', '--domain' => array('test', 'other')),
119
                1,
120
                array('1 messages are missing in the test domain', 'Checking the domains other, test'),
121
            ),
122
            'missing and obsolete message with obsolete only' => array(
123
                'en',
124
                array('messages' => array('foo' => 'bar'), 'test' => array('hello' => 'world')),
125
                'fr',
126
                array('messages' => array('foo' => 'bar', 'bar' => 'baz', 'old' => 'one')),
127
                array('locale' => 'fr', '--obsolete-only' => true),
128
                1,
129
                array('2 messages are obsolete in the messages domain'),
130
            ),
131
            'missing message with obsolete only' => array(
132
                'en',
133
                array('messages' => array('foo' => 'bar')),
134
                'fr',
135
                array('messages' => array()),
136
                array('locale' => 'fr', '--obsolete-only' => true),
137
                0,
138
                'The fr catalogue is in sync with the en one.',
139
            ),
140
        );
141
    }
142
143
    public function testFailsForNonExistentWhitelist()
144
    {
145
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
146
147
        $loader->getCatalogue('en')->willReturn(new MessageCatalogue('en', array('messages' => array('foo' => 'bar'))));
148
        $loader->getCatalogue('fr')->willReturn(new MessageCatalogue('fr', array('messages' => array('foo' => 'baz'))));
149
150
        $command = new CompareCommand($loader->reveal());
151
152
        $tester = new CommandTester($command);
153
        $exitCode = $tester->execute(array('locale' => 'fr', '--whitelist-file' => __DIR__.'/../fixtures/non_existent.yml'), array('decorated' => false));
154
155
        $this->assertEquals(1, $exitCode);
156
157
        $this->assertStringMatchesFormat('%AThe whitelist file "%s" does not exist.%A', $tester->getDisplay());
158
    }
159
160
    public function testFailsForInvalidWhitelist()
161
    {
162
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
163
164
        $loader->getCatalogue('en')->willReturn(new MessageCatalogue('en', array('messages' => array('foo' => 'bar'))));
165
        $loader->getCatalogue('fr')->willReturn(new MessageCatalogue('fr', array('messages' => array('foo' => 'baz'))));
166
167
        $command = new CompareCommand($loader->reveal());
168
169
        $tester = new CommandTester($command);
170
        $exitCode = $tester->execute(array('locale' => 'fr', '--whitelist-file' => __DIR__.'/../fixtures/invalid_whitelist.yml'), array('decorated' => false));
171
172
        $this->assertEquals(1, $exitCode);
173
174
        $this->assertStringMatchesFormat('%AThe whitelist file "%s" is invalid. It must be a Yaml file containing a map.%A', $tester->getDisplay());
175
    }
176
177
    public function testSucceedWithWhitelistedMessages()
178
    {
179
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
180
181
        $loader->getCatalogue('en')->willReturn(new MessageCatalogue('en', array('incenteev_tests' => array('foo' => 'bar', 'this key can go missing' => 'not defined in fr'))));
182
        $loader->getCatalogue('fr')->willReturn(new MessageCatalogue('fr', array('incenteev_tests' => array('foo' => 'baz', 'this.one.also' => 'obsolete... or no'))));
183
184
        $command = new CompareCommand($loader->reveal());
185
186
        $tester = new CommandTester($command);
187
        $exitCode = $tester->execute(array('locale' => 'fr', '--whitelist-file' => __DIR__.'/../fixtures/whitelist.yml'), array('decorated' => false));
188
189
        $this->assertEquals(0, $exitCode);
190
    }
191
192
    public function testSucceedWithWhitelistedMessagesAndMissingMessage()
193
    {
194
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
195
196
        $loader->getCatalogue('en')->willReturn(new MessageCatalogue('en', array('incenteev_tests' => array(
197
            'foo' => 'bar',
198
            'this key can go missing' => 'not defined in fr',
199
            'this key is required' => 'but missing in fr',
200
        ))));
201
        $loader->getCatalogue('fr')->willReturn(new MessageCatalogue('fr', array('incenteev_tests' => array('foo' => 'baz', 'this.one.also' => 'obsolete... or no'))));
202
203
        $command = new CompareCommand($loader->reveal());
204
205
        $tester = new CommandTester($command);
206
        $exitCode = $tester->execute(array('locale' => 'fr', '--whitelist-file' => __DIR__.'/../fixtures/whitelist.yml'), array('decorated' => false));
207
208
        $this->assertEquals(1, $exitCode);
209
210
        $this->assertContains('1 messages are missing in the incenteev_tests domain', $tester->getDisplay());
211
    }
212
213
    public function testWhitelistIsDomainBased()
214
    {
215
        $loader = $this->prophesize('Incenteev\TranslationCheckerBundle\Translator\ExposingTranslator');
216
217
        $loader->getCatalogue('en')->willReturn(new MessageCatalogue('en', array('messages' => array('foo' => 'bar', 'this key can go missing' => 'not defined in fr'))));
218
        $loader->getCatalogue('fr')->willReturn(new MessageCatalogue('fr', array('messages' => array('foo' => 'baz', 'this.one.also' => 'obsolete... or no'))));
219
220
        $command = new CompareCommand($loader->reveal());
221
222
        $tester = new CommandTester($command);
223
        $exitCode = $tester->execute(array('locale' => 'fr', '--whitelist-file' => __DIR__.'/../fixtures/whitelist.yml'), array('decorated' => false));
224
225
        $this->assertEquals(1, $exitCode);
226
227
        $this->assertContains('1 messages are obsolete in the messages domain', $tester->getDisplay());
228
        $this->assertContains('1 messages are missing in the messages domain', $tester->getDisplay());
229
    }
230
}
231