Completed
Push — master ( 03d25e...f3c75e )
by Christophe
16s queued 14s
created

testFailsWithWhitelistedMessagesAndMissingMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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