Passed
Push — 4 ( d81415...e2bea6 )
by Maxime
07:41
created

ConfigTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 354
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 205
c 1
b 0
f 0
dl 0
loc 354
rs 10
wmc 9

9 Methods

Rating   Name   Duplication   Size   Complexity  
A testUninheritedStatic() 0 30 1
A testUpdateWithFalsyValues() 0 29 1
A testNest() 0 20 1
A testMerges() 0 54 1
A testForClass() 0 12 1
A testCombinedStatic() 0 11 1
A testSetsFalsyDefaults() 0 7 1
B testUpdateStatic() 0 132 1
A testWithConfig() 0 37 1
1
<?php
2
3
namespace SilverStripe\Core\Tests\Config;
4
5
use SilverStripe\Config\Collections\MutableConfigCollectionInterface;
6
use SilverStripe\Config\MergeStrategy\Priority;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Dev\SapphireTest;
9
10
class ConfigTest extends SapphireTest
11
{
12
13
    public function testNest()
14
    {
15
        // Check basic config
16
        $this->assertEquals(3, Config::inst()->get(ConfigTest\TestNest::class, 'foo'));
17
        $this->assertEquals(5, Config::inst()->get(ConfigTest\TestNest::class, 'bar'));
18
19
        // Test nest copies data
20
        Config::nest();
21
        $this->assertEquals(3, Config::inst()->get(ConfigTest\TestNest::class, 'foo'));
22
        $this->assertEquals(5, Config::inst()->get(ConfigTest\TestNest::class, 'bar'));
23
24
        // Test nested data can be updated
25
        Config::modify()->merge(ConfigTest\TestNest::class, 'foo', 4);
26
        $this->assertEquals(4, Config::inst()->get(ConfigTest\TestNest::class, 'foo'));
27
        $this->assertEquals(5, Config::inst()->get(ConfigTest\TestNest::class, 'bar'));
28
29
        // Test unnest restores data
30
        Config::unnest();
31
        $this->assertEquals(3, Config::inst()->get(ConfigTest\TestNest::class, 'foo'));
32
        $this->assertEquals(5, Config::inst()->get(ConfigTest\TestNest::class, 'bar'));
33
    }
34
35
    public function testUpdateStatic()
36
    {
37
        // Test base state
38
        $this->assertEquals(
39
            ['test_1'],
40
            Config::inst()->get(ConfigTest\First::class, 'first')
41
        );
42
        $this->assertEquals(
43
            [
44
                'test_1',
45
                'test_2'
46
            ],
47
            Config::inst()->get(ConfigTest\Second::class, 'first')
48
        );
49
        $this->assertEquals(
50
            [ 'test_2' ],
51
            Config::inst()->get(ConfigTest\Second::class, 'first', Config::UNINHERITED)
52
        );
53
        $this->assertEquals(
54
            [
55
                'test_1',
56
                'test_2',
57
                'test_3'
58
            ],
59
            Config::inst()->get(ConfigTest\Third::class, 'first')
60
        );
61
        $this->assertEquals(
62
            [ 'test_3' ],
63
            Config::inst()->get(ConfigTest\Third::class, 'first', true)
64
        );
65
66
        // Modify first param
67
        Config::modify()->merge(ConfigTest\First::class, 'first', array('test_1_2'));
68
        Config::modify()->merge(ConfigTest\Third::class, 'first', array('test_3_2'));
69
        Config::modify()->merge(ConfigTest\Fourth::class, 'first', array('test_4'));
70
71
        // Check base class
72
        $this->assertEquals(
73
            ['test_1', 'test_1_2'],
74
            Config::inst()->get(ConfigTest\First::class, 'first')
75
        );
76
        $this->assertEquals(
77
            ['test_1', 'test_1_2'],
78
            Config::inst()->get(ConfigTest\First::class, 'first', Config::UNINHERITED)
79
        );
80
        $this->assertEquals(
81
            ['test_1'],
82
            Config::inst()->get(ConfigTest\First::class, 'first', Config::NO_DELTAS)
83
        );
84
        $this->assertEquals(
85
            ['test_1'],
86
            Config::inst()->get(ConfigTest\First::class, 'first', Config::NO_DELTAS | Config::UNINHERITED)
87
        );
88
89
        // Modify second param
90
        Config::modify()->merge(ConfigTest\Fourth::class, 'second', array('test_4'));
91
        Config::modify()->merge(ConfigTest\Third::class, 'second', array('test_3_2'));
92
93
        // Check fourth class
94
        $this->assertEquals(
95
            ['test_1', 'test_3', 'test_3_2', 'test_4'],
96
            Config::inst()->get(ConfigTest\Fourth::class, 'second')
97
        );
98
        $this->assertEquals(
99
            ['test_4'],
100
            Config::inst()->get(ConfigTest\Fourth::class, 'second', Config::UNINHERITED)
101
        );
102
        $this->assertEquals(
103
            ['test_1', 'test_3'],
104
            Config::inst()->get(ConfigTest\Fourth::class, 'second', Config::NO_DELTAS)
105
        );
106
        $this->assertEquals(
107
            null,
108
            Config::inst()->get(ConfigTest\Fourth::class, 'second', Config::NO_DELTAS | Config::UNINHERITED)
109
        );
110
111
        // Check third class
112
        $this->assertEquals(
113
            ['test_1', 'test_3', 'test_3_2'],
114
            Config::inst()->get(ConfigTest\Third::class, 'second')
115
        );
116
        $this->assertEquals(
117
            ['test_3', 'test_3_2'],
118
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::UNINHERITED)
119
        );
120
        $this->assertEquals(
121
            ['test_1', 'test_3'],
122
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::NO_DELTAS)
123
        );
124
        $this->assertEquals(
125
            ['test_3'],
126
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::NO_DELTAS | Config::UNINHERITED)
127
        );
128
129
        // Test remove()
130
        Config::modify()->remove(ConfigTest\Third::class, 'second');
131
132
        // Check third class ->get()
133
        $this->assertEquals(
134
            null,
135
            Config::inst()->get(ConfigTest\Third::class, 'second')
136
        );
137
        $this->assertEquals(
138
            ['test_1', 'test_3'],
139
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::NO_DELTAS)
140
        );
141
        $this->assertEquals(
142
            null,
143
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::UNINHERITED)
144
        );
145
146
        // Check ->exists()
147
        $this->assertFalse(
148
            Config::inst()->exists(ConfigTest\Third::class, 'second')
149
        );
150
        $this->assertFalse(
151
            Config::inst()->exists(ConfigTest\Third::class, 'second', Config::UNINHERITED)
152
        );
153
        $this->assertTrue(
154
            Config::inst()->exists(ConfigTest\Third::class, 'second', Config::NO_DELTAS)
155
        );
156
157
        // Test merge()
158
        Config::modify()->merge(ConfigTest\Third::class, 'second', ['test_3_2']);
159
        $this->assertEquals(
160
            ['test_3_2'],
161
            Config::inst()->get(ConfigTest\Third::class, 'second')
162
        );
163
        // No-deltas omits both above ->remove() as well as ->merge()
164
        $this->assertEquals(
165
            ['test_1', 'test_3'],
166
            Config::inst()->get(ConfigTest\Third::class, 'second', Config::NO_DELTAS)
167
        );
168
    }
169
170
    public function testUpdateWithFalsyValues()
171
    {
172
        // Booleans
173
        $this->assertTrue(Config::inst()->get(ConfigTest\First::class, 'bool'));
174
        Config::modify()->merge(ConfigTest\First::class, 'bool', false);
175
        $this->assertFalse(Config::inst()->get(ConfigTest\First::class, 'bool'));
176
        Config::modify()->merge(ConfigTest\First::class, 'bool', true);
177
        $this->assertTrue(Config::inst()->get(ConfigTest\First::class, 'bool'));
178
179
        // Integers
180
        $this->assertEquals(42, Config::inst()->get(ConfigTest\First::class, 'int'));
181
        Config::modify()->merge(ConfigTest\First::class, 'int', 0);
182
        $this->assertEquals(0, Config::inst()->get(ConfigTest\First::class, 'int'));
183
        Config::modify()->merge(ConfigTest\First::class, 'int', 42);
184
        $this->assertEquals(42, Config::inst()->get(ConfigTest\First::class, 'int'));
185
186
        // Strings
187
        $this->assertEquals('value', Config::inst()->get(ConfigTest\First::class, 'string'));
188
        Config::modify()->merge(ConfigTest\First::class, 'string', '');
189
        $this->assertEquals('', Config::inst()->get(ConfigTest\First::class, 'string'));
190
        Config::modify()->merge(ConfigTest\First::class, 'string', 'value');
191
        $this->assertEquals('value', Config::inst()->get(ConfigTest\First::class, 'string'));
192
193
        // Nulls
194
        $this->assertEquals('value', Config::inst()->get(ConfigTest\First::class, 'nullable'));
195
        Config::modify()->merge(ConfigTest\First::class, 'nullable', null);
196
        $this->assertNull(Config::inst()->get(ConfigTest\First::class, 'nullable'));
197
        Config::modify()->merge(ConfigTest\First::class, 'nullable', 'value');
198
        $this->assertEquals('value', Config::inst()->get(ConfigTest\First::class, 'nullable'));
199
    }
200
201
    public function testSetsFalsyDefaults()
202
    {
203
        $this->assertFalse(Config::inst()->get(ConfigTest\First::class, 'default_false'));
204
        // Technically the same as an undefined config key
205
        $this->assertNull(Config::inst()->get(ConfigTest\First::class, 'default_null'));
206
        $this->assertEquals(0, Config::inst()->get(ConfigTest\First::class, 'default_zero'));
207
        $this->assertEquals('', Config::inst()->get(ConfigTest\First::class, 'default_empty_string'));
208
    }
209
210
    public function testUninheritedStatic()
211
    {
212
        $this->assertEquals(Config::inst()->get(ConfigTest\First::class, 'third', Config::UNINHERITED), 'test_1');
213
        $this->assertEquals(Config::inst()->get(ConfigTest\Fourth::class, 'third', Config::UNINHERITED), null);
214
215
        Config::modify()->merge(ConfigTest\First::class, 'first', array('test_1b'));
216
        Config::modify()->merge(ConfigTest\Second::class, 'first', array('test_2b'));
217
218
        // Check that it can be applied to parent and subclasses, and queried directly
219
        $this->assertContains(
220
            'test_1b',
221
            Config::inst()->get(ConfigTest\First::class, 'first', Config::UNINHERITED)
222
        );
223
        $this->assertContains(
224
            'test_2b',
225
            Config::inst()->get(ConfigTest\Second::class, 'first', Config::UNINHERITED)
226
        );
227
228
        // But it won't affect subclasses - this is *uninherited* static
229
        $this->assertNotContains(
230
            'test_2b',
231
            Config::inst()->get(ConfigTest\Third::class, 'first', Config::UNINHERITED)
232
        );
233
        $this->assertNull(Config::inst()->get(ConfigTest\Fourth::class, 'first', Config::UNINHERITED));
234
235
        // Subclasses that don't have the static explicitly defined should allow definition, also
236
        // This also checks that set can be called after the first uninherited get()
237
        // call (which can be buggy due to caching)
238
        Config::modify()->merge(ConfigTest\Fourth::class, 'first', array('test_4b'));
239
        $this->assertContains('test_4b', Config::inst()->get(ConfigTest\Fourth::class, 'first', Config::UNINHERITED));
240
    }
241
242
    public function testCombinedStatic()
243
    {
244
        $this->assertEquals(
245
            ['test_1', 'test_2', 'test_3'],
246
            ConfigTest\Combined3::config()->get('first')
247
        );
248
249
        // Test that unset values are ignored
250
        $this->assertEquals(
251
            ['test_1', 'test_3'],
252
            ConfigTest\Combined3::config()->get('second')
253
        );
254
    }
255
256
    public function testMerges()
257
    {
258
        $result = Priority::mergeArray(
259
            ['A' => 1, 'B' => 2, 'C' => 3],
260
            ['C' => 4, 'D' => 5]
261
        );
262
        $this->assertEquals(
263
            ['A' => 1, 'B' => 2, 'C' => 3, 'D' => 5],
264
            $result
265
        );
266
267
        $result = Priority::mergeArray(
268
            ['C' => 4, 'D' => 5],
269
            ['A' => 1, 'B' => 2, 'C' => 3]
270
        );
271
        $this->assertEquals(
272
            ['A' => 1, 'B' => 2, 'C' => 4, 'D' => 5],
273
            $result
274
        );
275
276
        $result = Priority::mergeArray(
277
            [ 'C' => [4, 5, 6], 'D' => 5 ],
278
            [ 'A' => 1, 'B' => 2, 'C' => [1, 2, 3] ]
279
        );
280
        $this->assertEquals(
281
            ['A' => 1, 'B' => 2, 'C' => [1, 2, 3, 4, 5, 6], 'D' => 5],
282
            $result
283
        );
284
285
        $result = Priority::mergeArray(
286
            ['A' => 1, 'B' => 2, 'C' => [1, 2, 3]],
287
            ['C' => [4, 5, 6], 'D' => 5]
288
        );
289
        $this->assertEquals(
290
            ['A' => 1, 'B' => 2, 'C' => [4, 5, 6, 1, 2, 3], 'D' => 5],
291
            $result
292
        );
293
294
        $result = Priority::mergeArray(
295
            ['A' => 1, 'B' => 2, 'C' => ['Foo' => 1, 'Bar' => 2], 'D' => 3],
296
            ['C' => ['Bar' => 3, 'Baz' => 4]]
297
        );
298
        $this->assertEquals(
299
            ['A' => 1, 'B' => 2, 'C' => ['Foo' => 1, 'Bar' => 2, 'Baz' => 4], 'D' => 3],
300
            $result
301
        );
302
303
        $result = Priority::mergeArray(
304
            ['C' => ['Bar' => 3, 'Baz' => 4]],
305
            ['A' => 1, 'B' => 2, 'C' => ['Foo' => 1, 'Bar' => 2], 'D' => 3]
306
        );
307
        $this->assertEquals(
308
            ['A' => 1, 'B' => 2, 'C' => ['Foo' => 1, 'Bar' => 3, 'Baz' => 4], 'D' => 3],
309
            $result
310
        );
311
    }
312
313
    public function testForClass()
314
    {
315
        $config = ConfigTest\DefinesFoo::config();
316
        // Set values
317
        $this->assertTrue(isset($config->not_foo));
0 ignored issues
show
Bug Best Practice introduced by
The property not_foo does not exist on SilverStripe\Core\Config\Config_ForClass. Since you implemented __get, consider adding a @property annotation.
Loading history...
318
        $this->assertFalse(empty($config->not_foo));
319
        $this->assertEquals(1, $config->not_foo);
320
321
        // Unset values
322
        $this->assertFalse(isset($config->bar));
0 ignored issues
show
Bug Best Practice introduced by
The property bar does not exist on SilverStripe\Core\Config\Config_ForClass. Since you implemented __get, consider adding a @property annotation.
Loading history...
323
        $this->assertTrue(empty($config->bar));
324
        $this->assertNull($config->bar);
325
    }
326
327
    public function testWithConfig()
328
    {
329
        $oldValue = 'test_1';
330
        $newValue1 = 'new value 1';
331
        $newValue2 = 'new value 2';
332
        $property = 'third';
333
334
        $this->assertEquals(
335
            $oldValue,
336
            Config::inst()->get(ConfigTest\First::class, $property)
337
        );
338
339
        Config::withConfig(function (MutableConfigCollectionInterface $config) use ($newValue1, $newValue2, $property) {
340
            $config->set(ConfigTest\First::class, $property, $newValue1);
341
342
            $this->assertEquals(
343
                $newValue1,
344
                Config::inst()->get(ConfigTest\First::class, $property)
345
            );
346
347
            $resultValue = Config::withConfig(function (MutableConfigCollectionInterface $config) use ($newValue2, $property) {
348
                $config->set(ConfigTest\First::class, $property, $newValue2);
349
350
                return Config::inst()->get(ConfigTest\First::class, $property);
351
            });
352
353
            $this->assertEquals($newValue2, $resultValue);
354
355
            $this->assertEquals(
356
                $newValue1,
357
                Config::inst()->get(ConfigTest\First::class, $property)
358
            );
359
        });
360
361
        $this->assertEquals(
362
            $oldValue,
363
            Config::inst()->get(ConfigTest\First::class, $property)
364
        );
365
    }
366
}
367