CompareCommandTest   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 135
c 0
b 0
f 0
dl 0
loc 225
rs 10
wmc 8

7 Methods

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