Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Tests for the core_rtlcss class.
19
 *
20
 * The core_rtlcss class extends \MoodleHQ\RTLCSS\RTLCSS library which depends on sabberworm/php-css-parser library.
21
 * This test verifies that css parsing works as expected should any of the above change.
22
 *
23
 * @package    core
24
 * @category   phpunit
25
 * @copyright  2019 Jake Dallimore <jrhdallimore@gmail.com>
26
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 */
28
defined('MOODLE_INTERNAL') || die();
29
 
30
use Sabberworm\CSS\Parser;
31
use Sabberworm\CSS\OutputFormat;
32
 
33
/**
34
 * Class rtlcss_test.
35
 */
36
class rtlcss_test extends basic_testcase {
37
    /**
38
     * Data provider.
39
     * @return array
40
     */
41
    public function background_image_provider() {
42
        return [
43
            /* Not supported by MoodleHQ/RTLCSS yet.
44
            [[
45
                'should' => 'Should process string map in url (processUrls:true)',
46
                'expected' => 'div { background-image: url(images/rtl.png), url(images/right.png);}',
47
                'input'    => 'div { background-image: url(images/ltr.png), url(images/left.png);}',
48
                'reversable' => true,
49
                'options' => [ 'processUrls' => true ],
50
                'skip' => true
51
            ]],
52
            [[
53
                'should' => 'Should not negate color value for linear gradient',
54
                'expected' => 'div { background-image: linear-gradient(rgba(255, 255, 255, 0.3) 0%, #ff8 100%);}',
55
                'input'    => 'div { background-image: linear-gradient(rgba(255, 255, 255, 0.3) 0%, #ff8 100%);}',
56
                'reversable' => true,
57
                'skip' => true
58
            ]],
59
            [[
60
                'should' => 'Should not negate color value for linear gradient with calc',
61
                'expected' => 'div { background-image: linear-gradient(rgba(255, 255, calc((125 * 2) + 5), 0.3) 0%, #ff8 100%);}',
62
                'input'    => 'div { background-image: linear-gradient(rgba(255, 255, calc((125 * 2) + 5), 0.3) 0%, #ff8 100%);}',
63
                'reversable' => true,
64
                'skip' => true
65
            ]],
66
            [[
67
                'should' => 'Should negate angle value for linear gradient',
68
                'expected' => 'div { background-image: linear-gradient(13.25deg, rgba(255, 255, 255, .15) 25%, transparent 25%);}',
69
                'input'    => 'div { background-image: linear-gradient(-13.25deg, rgba(255, 255, 255, .15) 25%, transparent 25%);}',
70
                'reversable' => true,
71
                'skip' => true
72
            ]]
73
            */
74
        ];
75
    }
76
 
77
    /**
78
     * Data provider.
79
     * @return array
80
     */
81
    public function background_position_provider() {
82
        return [
83
            [[
84
                'should' => 'Should complement percentage horizontal position ',
85
                'expected' => 'div {background-position:100% 75%;}',
86
                'input' => 'div {background-position:0 75%;}',
87
                'reversable' => false
88
            ]],
89
            /* Not supported by MoodleHQ/RTLCSS yet.
90
            [[
91
                'should' => 'Should complement percentage horizontal position with calc',
92
                'expected' => 'div {background-position:calc(100% - (30% + 50px)) 75%;}',
93
                'input' => 'div {background-position:calc(30% + 50px) 75%;}',
94
                'reversable' => false,
95
                'skip' => true
96
            ]],
97
            [[
98
                'should' => 'Should complement percentage horizontal position ',
99
                'expected' => 'div {background-position:81.25% 75%, 10.75% top;}',
100
                'input' => 'div {background-position:18.75% 75%, 89.25% top;}',
101
                'reversable' => true,
102
                'skip' => true
103
            ]],
104
            [[
105
                'should' => 'Should complement percentage horizontal position with calc',
106
                'expected' => 'div {background-position:calc(100% - (30% + 50px)) calc(30% + 50px), 10.75% top;}',
107
                'input' => 'div {background-position:calc(30% + 50px) calc(30% + 50px), 89.25% top;}',
108
                'reversable' => false,
109
                'skip' => true
110
            ]],
111
            [[
112
                'should' => 'Should swap left with right',
113
                'expected' => 'div {background-position:right 75%, left top;}',
114
                'input' => 'div {background-position:left 75%, right top;}',
115
                'reversable' => true,
116
                'skip' => true
117
            ]],
118
            [[
119
                'should' => 'Should swap left with right wit calc',
120
                'expected' => 'div {background-position:right -ms-calc(30% + 50px), left top;}',
121
                'input' => 'div {background-position:left -ms-calc(30% + 50px), right top;}',
122
                'reversable' => true,
123
                'skip' => true
124
            ]],
125
            */
126
            [[
127
                'should' => 'Should complement percentage: position-x (treat 0 as 0%)',
128
                'expected' => 'div {background-position-x:100%, 0%;}',
129
                'input' => 'div {background-position-x:0, 100%;}',
130
                'reversable' => false
131
            ]],
132
            [[
133
                'should' => 'Should complement percentage: position-x',
134
                'expected' => 'div {background-position-x:81.75%, 11%;}',
135
                'input' => 'div {background-position-x:18.25%, 89%;}',
136
                'reversable' => true
137
            ]],
138
            /* Not supported by MoodleHQ/RTLCSS yet.
139
            [[
140
                'should' => 'Should complement percentage with calc: position-x',
141
                'expected' => 'div {background-position-x:calc(100% - (30% + 50px)), -webkit-calc(100% - (30% + 50px));}',
142
                'input' => 'div {background-position-x:calc(30% + 50px), -webkit-calc(30% + 50px);}',
143
                'reversable' => false,
144
                'skip' => true
145
            ]],
146
            */
147
            [[
148
                'should' => 'Should swap left with right: position-x',
149
                'expected' => 'div {background-position-x:right, left;}',
150
                'input' => 'div {background-position-x:left, right;}',
151
                'reversable' => true
152
            ]],
153
            [[
154
                'should' => 'Should keep as is: position-x',
155
                'expected' => 'div {background-position-x:100px, 0px;}',
156
                'input' => 'div {background-position-x:100px, 0px;}',
157
                'reversable' => true
158
            ]],
159
 
160
            [[
161
                'should' => 'Should flip when using 3 positions',
162
                'expected' => 'div {background-position:center right 1px;}',
163
                'input' => 'div {background-position:center left 1px;}',
164
                'reversable' => true
165
            ]],
166
            [[
167
                'should' => 'Should flip when using 4 positions',
168
                'expected' => 'div {background-position:center 2px right 1px;}',
169
                'input' => 'div {background-position:center 2px left 1px;}',
170
                'reversable' => true
171
            ]],
172
            [[
173
                'should' => 'Should flip when using 4 positions mixed',
174
                'expected' => 'div {background-position:right 2px bottom 1px;}',
175
                'input' => 'div {background-position:left 2px bottom 1px;}',
176
                'reversable' => true
177
            ]]
178
        ];
179
    }
180
 
181
    /**
182
     * Data provider.
183
     * @return array
184
     */
185
    public function background_provider() {
186
        return [
187
            [[
188
                'should' => 'Should treat 0 as 0%',
189
                'expected' => '.banner { background: 100% top url("topbanner.png") #00d repeat-y fixed; }',
190
                'input' => '.banner { background: 0 top url("topbanner.png") #00d repeat-y fixed; }',
191
                'reversable' => false
192
            ]],
193
            [[
194
                'should' => 'Should complement percentage horizontal position',
195
                'expected' => '.banner { background: 81% top url("topbanner.png") #00d repeat-y fixed; }',
196
                'input' => '.banner { background: 19% top url("topbanner.png") #00d repeat-y fixed; }',
197
                'reversable' => true
198
            ]],
199
            /* Not supported by MoodleHQ/RTLCSS yet.
200
            [[
201
                'should' => 'Should complement calc horizontal position',
202
                'expected' => '.banner { background: calc(100% - (19% + 2px)) top url(topbanner.png) #00d repeat-y fixed; }',
203
                'input' => '.banner { background: calc(19% + 2px) top url(topbanner.png) #00d repeat-y fixed; }',
204
                'reversable' => false,
205
                'skip' => true
206
            ]],
207
            */
208
            [[
209
                'should' => 'Should mirror keyword horizontal position',
210
                'expected' => '.banner { background: right top url("topbanner.png") #00d repeat-y fixed; }',
211
                'input' => '.banner { background: left top url("topbanner.png") #00d repeat-y fixed; }',
212
                'reversable' => true
213
            ]],
214
            [[
215
                'should' => 'Should not process string map in url (default)',
216
                'expected' => '.banner { background: 10px top url("ltr-top-right-banner.png") #00d repeat-y fixed; }',
217
                'input' => '.banner { background: 10px top url("ltr-top-right-banner.png") #00d repeat-y fixed; }',
218
                'reversable' => true
219
            ]],
220
            /* Not supported by MoodleHQ/RTLCSS yet.
221
            [[
222
                'should' => 'Should process string map in url (processUrls:true)',
223
                'expected' => '.banner { background: 10px top url(rtl-top-left-banner.png) #00d repeat-y fixed; }',
224
                'input' => '.banner { background: 10px top url(ltr-top-right-banner.png) #00d repeat-y fixed; }',
225
                'reversable' => true,
226
                'options' => [ 'processUrls' => true ],
227
                'skip' => true
228
            ]],
229
            [[
230
                'should' => 'Should process string map in url (processUrls:{decl:true})',
231
                'expected' => '.banner { background: 10px top url(rtl-top-left-banner.png) #00d repeat-y fixed; }',
232
                'input' => '.banner { background: 10px top url(ltr-top-right-banner.png) #00d repeat-y fixed; }',
233
                'reversable' => true,
234
                'options' => [ 'processUrls' => [ 'decl' => true ] ],
235
                'skip' => true
236
            ]],
237
            */
238
            [[
239
                'should' => 'Should not process string map in url (processUrls:{atrule:true})',
240
                'expected' => '.banner { background: 10px top url("ltr-top-right-banner.png") #00d repeat-y fixed; }',
241
                'input' => '.banner { background: 10px top url("ltr-top-right-banner.png") #00d repeat-y fixed; }',
242
                'reversable' => true,
243
                'options' => [ 'processUrls' => [ 'atrule' => true ] ]
244
            ]],
245
            [[
246
                'should' => 'Should not swap bright:bleft, ultra:urtla',
247
                'expected' => '.banner { background: 10px top url("ultra/bright.png") #00d repeat-y fixed; }',
248
                'input' => '.banner { background: 10px top url("ultra/bright.png") #00d repeat-y fixed; }',
249
                'reversable' => true
250
            ]],
251
            /* Not supported by MoodleHQ/RTLCSS yet.
252
            [[
253
                'should' => 'Should swap bright:bleft, ultra:urtla (processUrls: true, greedy)',
254
                'expected' => '.banner { background: 10px top url("urtla/bleft.png") #00d repeat-y fixed; }',
255
                'input' => '.banner { background: 10px top url("ultra/bright.png") #00d repeat-y fixed; }',
256
                'reversable' => true,
257
                'options' => [ 'processUrls' => true, 'greedy' => true ],
258
                'skip' => true
259
            ]],
260
            */
261
            [[
262
                'should' => 'Should not flip hex colors ',
263
                'expected' => '.banner { background: #ff0; }',
264
                'input' => '.banner { background: #ff0; }',
265
                'reversable' => true
266
            ]]
267
        ];
268
    }
269
 
270
    /**
271
     * Data provider.
272
     * @return array
273
     */
274
    public function directives_provider() {
275
        return [
276
            [[
277
                'should' => 'Should ignore flipping - rule level (default)',
278
                'expected' => 'div {left:10px;text-align:right;}',
279
                'input' => '/*rtl:ignore*/div { left:10px; text-align:right;}',
280
                'reversable' => false
281
            ]],
282
            [[
283
                'should' => 'Should ignore flipping - rule level (!important comment)',
284
                'expected' => 'div {left:10px;text-align:right;}',
285
                'input' => '/*!rtl:ignore*/div { left:10px; text-align:right;}',
286
                'reversable' => false,
287
            ]],
288
            // Not supported by MoodleHQ/RTLCSS yet.
289
            //[[
290
            //    'should' => 'Should ignore flipping - decl. level (default)',
291
            //    'expected' => 'div {left:10px;text-align:left;}',
292
            //    'input' => 'div {left:10px/*rtl:ignore*/;text-align:right;}',
293
            //    'reversable' => false,
294
            //    'skip' => true
295
            //]],
296
            [[
297
                'should' => 'Should add raw css rules',
298
                'expected' => 'div {left:10px;text-align:right;} a {display:block;}',
299
                'input' => '/*rtl:raw: div { left:10px;text-align:right;}*/ a {display:block;}',
300
                'reversable' => false
301
            ]],
302
            [[
303
                'should' => 'Should add raw css declarations',
304
                'expected' => 'div {font-family:"Droid Kufi Arabic";right:10px;text-align:left;}',
305
                'input' => 'div { /*rtl:raw: font-family: "Droid Kufi Arabic";*/ left:10px;text-align:right;}',
306
                'reversable' => false
307
            ]],
308
            [[
309
                'should' => 'Should support block-style',
310
                'expected' => 'div {left:10px;text-align:right;}',
311
                'input' => ' div {/*rtl:begin:ignore*/left:10px;/*rtl:end:ignore*/ text-align:left;}',
312
                'reversable' => false
313
            ]],
314
            [[
315
                'should' => 'Should support none block-style',
316
                'expected' => 'div {left:10px;text-align:left;}',
317
                'input' => ' /*rtl:ignore*/div {left:10px; text-align:left;}',
318
                'reversable' => false
319
            ]],
320
            [[
321
                'should' => 'Should remove rules (block-style)',
322
                'expected' => 'b {float:right;}',
323
                'input' => ' /*rtl:begin:remove*/div {left:10px; text-align:left;} a { display:block;} /*rtl:end:remove*/ b{float:left;}',
324
                'reversable' => false
325
            ]],
326
            [[
327
                'should' => 'Should remove rules',
328
                'expected' => 'a {display:block;} b {float:right;}',
329
                'input' => ' /*rtl:remove*/div {left:10px; text-align:left;} a { display:block;} b{float:left;}',
330
                'reversable' => false
331
            ]],
332
            [[
333
                'should' => 'Should remove declarations',
334
                'expected' => 'div {text-align:right;}',
335
                'input' => 'div {/*rtl:remove*/left:10px; text-align:left;}',
336
                'reversable' => false
337
            ]],
338
            [[
339
                'should' => 'Should remove declarations (block-style)',
340
                'expected' => 'div {display:inline;}',
341
                'input' => 'div {/*rtl:begin:remove*/left:10px; text-align:left;/*rtl:end:remove*/ display:inline;}',
342
                'reversable' => false
343
            ]],
344
            // Not supported by MoodleHQ/RTLCSS yet.
345
            //[[
346
            //    'should' => 'Final/trailing comment ignored bug (block style): note a tag rules are NOT flipped as they should be',
347
            //    'expected' => 'div {left:10px;text-align:left;} a {right:10px;}',
348
            //    'input' => 'div {/*rtl:begin:ignore*/left:10px; text-align:left;/*rtl:end:ignore*/} a {left:10px;}',
349
            //    'reversable' => false,
350
            //    'skip' => true
351
            //]]
352
        ];
353
    }
354
 
355
    /**
356
     * Data provider.
357
     * @return array
358
     */
359
    public function properties_provider() {
360
        return [
361
            [[
362
                'should' => 'Should mirror property name: border-top-right-radius',
363
                'expected' => 'div { border-top-left-radius:15px; }',
364
                'input' => 'div { border-top-right-radius:15px; }',
365
                'reversable' => true
366
            ]],
367
            [[
368
                'should' => 'Should mirror property name: border-bottom-right-radius',
369
                'expected' => 'div { border-bottom-left-radius:15px; }',
370
                'input' => 'div { border-bottom-right-radius:15px; }',
371
                'reversable' => true
372
            ]],
373
            [[
374
                'should' => 'Should mirror property name: border-left',
375
                'expected' => 'div { border-right:1px solid black; }',
376
                'input' => 'div { border-left:1px solid black; }',
377
                'reversable' => true
378
            ]],
379
            [[
380
                'should' => 'Should mirror property name: border-left-color',
381
                'expected' => 'div { border-right-color:black; }',
382
                'input' => 'div { border-left-color:black; }',
383
                'reversable' => true
384
            ]],
385
            [[
386
                'should' => 'Should mirror property name: border-left-style',
387
                'expected' => 'div { border-right-style:solid; }',
388
                'input' => 'div { border-left-style:solid; }',
389
                'reversable' => true
390
            ]],
391
            [[
392
                'should' => 'Should mirror property name: border-left-width',
393
                'expected' => 'div { border-right-width:1em; }',
394
                'input' => 'div { border-left-width:1em; }',
395
                'reversable' => true
396
            ]],
397
            [[
398
                'should' => 'Should mirror property name: left',
399
                'expected' => 'div { right:auto; }',
400
                'input' => 'div { left:auto; }',
401
                'reversable' => true
402
            ]],
403
            [[
404
                'should' => 'Should mirror property name: margin-left',
405
                'expected' => 'div { margin-right:2em; }',
406
                'input' => 'div { margin-left:2em; }',
407
                'reversable' => true
408
            ]],
409
            [[
410
                'should' => 'Should mirror property name: padding-left',
411
                'expected' => 'div { padding-right:2em; }',
412
                'input' => 'div { padding-left:2em; }',
413
                'reversable' => true
414
            ]]
415
        ];
416
    }
417
 
418
    /**
419
     * Data provider.
420
     * @return array
421
     */
422
    public function special_provider() {
423
        return [
424
            /* Not supported by MoodleHQ/RTLCSS yet.
425
            [[
426
                'should' => 'Should not negate tokens',
427
                'expected' => 'div { box-shadow: rgba(0, 128, 128, .98) inset -5em 1em 0;}',
428
                'input' => 'div { box-shadow: rgba(0, 128, 128, .98) inset 5em 1em 0;}',
429
                'reversable' => true,
430
                'skip' => true,
431
            ]]
432
            */
433
        ];
434
    }
435
 
436
    /**
437
     * Data provider.
438
     * @return array
439
     */
440
    public function transform_origin_provider() {
441
        return [
442
            [[
443
                'should' => 'Should mirror (x-offset: 0 means 0%)',
444
                'expected' => 'div { transform-origin:100%; }',
445
                'input' => 'div { transform-origin:0; }',
446
                'reversable' => false
447
            ]],
448
            [[
449
                'should' => 'Should mirror (x-offset)',
450
                'expected' => 'div { transform-origin:90.25%; }',
451
                'input' => 'div { transform-origin:9.75%; }',
452
                'reversable' => true
453
            ]],
454
            /* Not supported by MoodleHQ/RTLCSS yet.
455
            [[
456
                'should' => 'Should mirror calc (x-offset)',
457
                'expected' => 'div { transform-origin: -moz-calc(100% - (((25%/2) * 10px))); }',
458
                'input' => 'div { transform-origin: -moz-calc(((25%/2) * 10px)); }',
459
                'reversable' => false,
460
                'skip' => true
461
            ]],
462
            */
463
            [[
464
                'should' => 'Should not mirror (x-offset: not percent, not calc)',
465
                'expected' => 'div { transform-origin:10.75px; }',
466
                'input' => 'div { transform-origin:10.75px; }',
467
                'reversable' => false
468
            ]],
469
            [[
470
                'should' => 'Should mirror (offset-keyword)',
471
                'expected' => 'div { transform-origin:right; }',
472
                'input' => 'div { transform-origin:left; }',
473
                'reversable' => true
474
            ]],
475
            [[
476
                'should' => 'Should mirror (x-offset y-offset: 0 means 0%)',
477
                'expected' => 'div { transform-origin:100% 0; }',
478
                'input' => 'div { transform-origin:0 0; }',
479
                'reversable' => false
480
            ]],
481
            /* Not supported by MoodleHQ/RTLCSS yet.
482
            [[
483
                'should' => 'Should mirror with y being calc (x-offset y-offset: 0 means 0%)',
484
                'expected' => 'div { transform-origin:100% -webkit-calc(15% * (3/2)); }',
485
                'input' => 'div { transform-origin:0 -webkit-calc(15% * (3/2)); }',
486
                'reversable' => false,
487
                'skip' => true
488
            ]],
489
            */
490
            [[
491
                'should' => 'Should mirror percent (x-offset y-offset)',
492
                'expected' => 'div { transform-origin:30.25% 10%; }',
493
                'input' => 'div { transform-origin:69.75% 10%; }',
494
                'reversable' => true
495
            ]],
496
            /* Not supported by MoodleHQ/RTLCSS yet.
497
            [[
498
                'should' => 'Should mirror with x being calc (x-offset y-offset)',
499
                'expected' => 'div { transform-origin: -webkit-calc(100% - (15% * (3/2))) 30.25%; }',
500
                'input' => 'div { transform-origin: -webkit-calc(15% * (3/2)) 30.25%; }',
501
                'reversable' => false,
502
                'skip' => true
503
            ]],
504
            [[
505
                'should' => 'Should mirror with y being calc (x-offset y-offset)',
506
                'expected' => 'div { transform-origin:30.25% calc(15% * (3/2)); }',
507
                'input' => 'div { transform-origin:69.75% calc(15% * (3/2)); }',
508
                'reversable' => true,
509
                'skip' => true
510
            ]],
511
            */
512
            [[
513
                'should' => 'Should mirror (y-offset x-offset-keyword)',
514
                'expected' => 'div { transform-origin:70% right; }',
515
                'input' => 'div { transform-origin:70% left; }',
516
                'reversable' => true
517
            ]],
518
            /* Not supported by MoodleHQ/RTLCSS yet.
519
            [[
520
                'should' => 'Should mirror with calc (y-offset x-offset-keyword)',
521
                'expected' => 'div { transform-origin:-ms-calc(140%/2) right; }',
522
                'input' => 'div { transform-origin:-ms-calc(140%/2) left; }',
523
                'reversable' => true,
524
                'skip' => true
525
            ]],
526
            */
527
            [[
528
                'should' => 'Should mirror (x-offset-keyword y-offset)',
529
                'expected' => 'div { transform-origin:right 70%; }',
530
                'input' => 'div { transform-origin:left 70%; }',
531
                'reversable' => true
532
            ]],
533
            /* Not supported by MoodleHQ/RTLCSS yet.
534
            [[
535
                'should' => 'Should mirror with calc (x-offset-keyword y-offset)',
536
                'expected' => 'div { transform-origin:right -moz-calc(((140%/2))); }',
537
                'input' => 'div { transform-origin:left -moz-calc(((140%/2))); }',
538
                'reversable' => true,
539
                'skip' => true
540
            ]],
541
            */
542
            [[
543
                'should' => 'Should mirror (y-offset-keyword x-offset)',
544
                'expected' => 'div { transform-origin:top 30.25%; }',
545
                'input' => 'div { transform-origin:top 69.75%; }',
546
                'reversable' => true
547
            ]],
548
            /* Not supported by MoodleHQ/RTLCSS yet.
549
            [[
550
                'should' => 'Should not mirror with x being calc (y-offset-keyword x-offset)',
551
                'expected' => 'div { transform-origin:top calc(100% - (((140%/2)))); }',
552
                'input' => 'div { transform-origin:top calc(((140%/2))); }',
553
                'reversable' => false,
554
                'skip' => true
555
            ]],
556
            */
557
            [[
558
                'should' => 'Should mirror (x-offset-keyword y-offset-keyword)',
559
                'expected' => 'div { transform-origin:right top; }',
560
                'input' => 'div { transform-origin:left top; }',
561
                'reversable' => true
562
            ]],
563
            [[
564
                'should' => 'Should mirror (y-offset-keyword x-offset-keyword)',
565
                'expected' => 'div { transform-origin:top right; }',
566
                'input' => 'div { transform-origin:top left; }',
567
                'reversable' => true
568
            ]],
569
            [[
570
                'should' => 'Should mirror (x-offset y-offset z-offset)',
571
                'expected' => 'div { transform-origin:80.25% 30% 10%; }',
572
                'input' => 'div { transform-origin:19.75% 30% 10%; }',
573
                'reversable' => true
574
            ]],
575
            /* Not supported by MoodleHQ/RTLCSS yet.
576
            [[
577
                'should' => 'Should mirror with x being calc (x-offset y-offset z-offset)',
578
                'expected' => 'div { transform-origin: calc(100% - (25% * 3 + 20px)) 30% 10%; }',
579
                'input' => 'div { transform-origin: calc(25% * 3 + 20px) 30% 10%; }',
580
                'reversable' => false,
581
                'skip' => true
582
            ]],
583
            */
584
            [[
585
                'should' => 'Should mirror (y-offset x-offset-keyword z-offset)',
586
                'expected' => 'div { transform-origin:20% right 10%; }',
587
                'input' => 'div { transform-origin:20% left 10%; }',
588
                'reversable' => true
589
            ]],
590
            [[
591
                'should' => 'Should mirror (x-offset-keyword y-offset z-offset)',
592
                'expected' => 'div { transform-origin:left 20% 10%; }',
593
                'input' => 'div { transform-origin:right 20% 10%; }',
594
                'reversable' => true
595
            ]],
596
            [[
597
                'should' => 'Should mirror (x-offset-keyword y-offset-keyword z-offset)',
598
                'expected' => 'div { transform-origin:left bottom 10%; }',
599
                'input' => 'div { transform-origin:right bottom 10%; }',
600
                'reversable' => true
601
            ]],
602
            [[
603
                'should' => 'Should mirror (y-offset-keyword x-offset-keyword z-offset)',
604
                'expected' => 'div { transform-origin:bottom left 10%; }',
605
                'input' => 'div { transform-origin:bottom right 10%; }',
606
                'reversable' => true
607
            ]]
608
        ];
609
    }
610
 
611
    /**
612
     * Data provider.
613
     * @return array
614
     */
615
    public function transforms_provider() {
616
        return [
617
            /* Not supported by MoodleHQ/RTLCSS yet.
618
            [[
619
                'should' => 'Should mirror transform : matrix',
620
                'expected' => 'div { transform: matrix(2, 0.1, 20.75, 2, 2, 2); }',
621
                'input' => 'div { transform: matrix(2, -0.1, -20.75, 2, -2, 2); }',
622
                'reversable' => true,
623
                'skip' => true
624
            ]],
625
            [[
626
                'should' => 'Should mirror transform (with no digits before dot): matrix',
627
                'expected' => 'div { transform: matrix(2, 0.1, 0.75, 2, 2, 2); }',
628
                'input' => 'div { transform: matrix(2, -0.1, -.75, 2, -2, 2); }',
629
                'reversable' => false,
630
                'skip' => true
631
            ]],
632
            [[
633
                'should' => 'Should mirror transform with calc: matrix',
634
                'expected' => 'div { transform: matrix( -moz-calc(((25%/2) * 10px)), calc(-1*(((25%/2) * 10px))), 20.75, 2, 2, 2 ); }',
635
                'input' => 'div { transform: matrix( -moz-calc(((25%/2) * 10px)), calc(((25%/2) * 10px)), -20.75, 2, -2, 2 ); }',
636
                'reversable' => false,
637
                'skip' => true
638
            ]],
639
            [[
640
                'should' => 'Should mirror transform : matrix3d',
641
                'expected' => 'div { transform:matrix3d(0.227114470162179, 0.127248412323519, 0, 0.000811630714323203, 0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, -165, 67, 0, 1); }',
642
                'input' => 'div { transform:matrix3d(0.227114470162179, -0.127248412323519, 0, -0.000811630714323203, -0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, 165, 67, 0, 1); }',
643
                'reversable' => true,
644
                'skip' => true
645
            ]],
646
            [[
647
                'should' => 'Should mirror transform (with no digits before dot): matrix3d',
648
                'expected' => 'div { transform:matrix3d(0.227114470162179, 0.127248412323519, 0, 0.000811630714323203, 0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, -165, 67, 0, 1); }',
649
                'input' => 'div { transform:matrix3d(0.227114470162179, -.127248412323519, 0, -0.000811630714323203, -0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, 165, 67, 0, 1); }',
650
                'reversable' => false,
651
                'skip' => true
652
            ]],
653
            [[
654
                'should' => 'Should mirror transform with calc : matrix3d',
655
                'expected' => 'div { transform:matrix3d(0.227114470162179, 0.127248412323519, 0, 0.000811630714323203, 0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, calc(-1*(((25%/2) * 10px))), 67, 0, 1); }',
656
                'input' => 'div { transform:matrix3d(0.227114470162179, -0.127248412323519, 0, -0.000811630714323203, -0.113139853456515, 1.53997196559414, 0, 0.000596368270149729, 0, 0, 1, 0, calc(((25%/2) * 10px)), 67, 0, 1); }',
657
                'reversable' => false,
658
                'skip' => true
659
            ]],
660
            [[
661
                'should' => 'Should mirror transform : translate',
662
                'expected' => 'div { transform: translate(-10.75px); }',
663
                'input' => 'div { transform: translate(10.75px); }',
664
                'reversable' => true,
665
                'skip' => true
666
            ]],
667
            [[
668
                'should' => 'Should mirror transform (with no digits before dot): translate',
669
                'expected' => 'div { transform: translate(-0.75px); }',
670
                'input' => 'div { transform: translate(.75px); }',
671
                'reversable' => false,
672
                'skip' => true
673
            ]],
674
            [[
675
                'should' => 'Should mirror transform with calc: translate',
676
                'expected' => 'div { transform: translate(-moz-calc(-1*(((25%/2) * 10px)))); }',
677
                'input' => 'div { transform: translate(-moz-calc(((25%/2) * 10px))); }',
678
                'reversable' => false,
679
                'skip' => true
680
            ]],
681
            [[
682
                'should' => 'Should mirror transform : translateX',
683
                'expected' => 'div { transform: translateX(-50.25px); }',
684
                'input' => 'div { transform: translateX(50.25px); }',
685
                'reversable' => true,
686
                'skip' => true
687
            ]],
688
            [[
689
                'should' => 'Should mirror transform (with no digits before dot): translateX',
690
                'expected' => 'div { transform: translateX(-0.25px); }',
691
                'input' => 'div { transform: translateX(.25px); }',
692
                'reversable' => false,
693
                'skip' => true
694
            ]],
695
            [[
696
                'should' => 'Should mirror transform with calc : translateX',
697
                'expected' => 'div { transform: translateX(-ms-calc(-1*(((25%/2) * 10px))))); }',
698
                'input' => 'div { transform: translateX(-ms-calc(((25%/2) * 10px)))); }',
699
                'reversable' => false,
700
                'skip' => true
701
            ]],
702
            [[
703
                'should' => 'Should mirror transform : translate3d',
704
                'expected' => 'div { transform: translate3d(-12.75px, 50%, 3em); }',
705
                'input' => 'div { transform: translate3d(12.75px, 50%, 3em); }',
706
                'reversable' => true,
707
                'skip' => true
708
            ]],
709
            [[
710
                'should' => 'Should mirror transform (with no digits before dot): translate3d',
711
                'expected' => 'div { transform: translate3d(-0.75px, 50%, 3em); }',
712
                'input' => 'div { transform: translate3d(.75px, 50%, 3em); }',
713
                'reversable' => false,
714
                'skip' => true
715
            ]],
716
            [[
717
                'should' => 'Should mirror transform with calc: translate3d',
718
                'expected' => 'div { transform: translate3d(-webkit-calc(-1*(((25%/2) * 10px))))), 50%, calc(((25%/2) * 10px))))); }',
719
                'input' => 'div { transform: translate3d(-webkit-calc(((25%/2) * 10px)))), 50%, calc(((25%/2) * 10px))))); }',
720
                'reversable' => false,
721
                'skip' => true
722
            ]],
723
            [[
724
                'should' => 'Should mirror transform : rotate',
725
                'expected' => 'div { transform: rotate(-20.75deg); }',
726
                'input' => 'div { transform: rotate(20.75deg); }',
727
                'reversable' => true,
728
                'skip' => true
729
            ]],
730
            [[
731
                'should' => 'Should mirror transform (with no digits before dot): rotate',
732
                'expected' => 'div { transform: rotate(-0.75deg); }',
733
                'input' => 'div { transform: rotate(.75deg); }',
734
                'reversable' => false,
735
                'skip' => true
736
            ]],
737
            [[
738
                'should' => 'Should mirror transform with calc: rotate',
739
                'expected' => 'div { transform: rotate(calc(-1*(((25%/2) * 10deg)))); }',
740
                'input' => 'div { transform: rotate(calc(((25%/2) * 10deg))); }',
741
                'reversable' => false,
742
                'skip' => true
743
            ]],
744
            [[
745
                'should' => 'Should mirror transform : rotate3d',
746
                'expected' => 'div { transform: rotate3d(10, -20.15, 10, -45.14deg); }',
747
                'input' => 'div { transform: rotate3d(10, 20.15, 10, 45.14deg); }',
748
                'reversable' => true,
749
                'skip' => true
750
            ]],
751
            [[
752
                'should' => 'Should mirror transform (with no digits before dot): rotate3d',
753
                'expected' => 'div { transform: rotate3d(10, -20, 10, -0.14deg); }',
754
                'input' => 'div { transform: rotate3d(10, 20, 10, .14deg); }',
755
                'reversable' => false,
756
                'skip' => true
757
            ]],
758
            [[
759
                'should' => 'Should mirror transform with calc: rotate3d',
760
                'expected' => 'div { transform: rotate3d(10, -20.15, 10, calc(-1*(((25%/2) * 10deg)))); }',
761
                'input' => 'div { transform: rotate3d(10, 20.15, 10, calc(((25%/2) * 10deg))); }',
762
                'reversable' => false,
763
                'skip' => true
764
            ]],
765
            [[
766
                'should' => 'Should not mirror transform : rotateX',
767
                'expected' => 'div { transform: rotateX(45deg); }',
768
                'input' => 'div { transform: rotateX(45deg); }',
769
                'reversable' => false,
770
                'skip' => true
771
            ]],
772
            [[
773
                'should' => 'Should not mirror transform with calc: rotateX',
774
                'expected' => 'div { transform: rotateX(calc(((25%/2) * 10deg))); }',
775
                'input' => 'div { transform: rotateX(calc(((25%/2) * 10deg))); }',
776
                'reversable' => false,
777
                'skip' => true
778
            ]],
779
            [[
780
                'should' => 'Should not mirror transform : rotateY',
781
                'expected' => 'div { transform: rotateY(45deg); }',
782
                'input' => 'div { transform: rotateY(45deg); }',
783
                'reversable' => false,
784
                'skip' => true
785
            ]],
786
            [[
787
                'should' => 'Should not mirror transform with calc: rotateY',
788
                'expected' => 'div { transform: rotateY(calc(((25%/2) * 10deg))); }',
789
                'input' => 'div { transform: rotateY(calc(((25%/2) * 10deg))); }',
790
                'reversable' => false,
791
                'skip' => true
792
            ]],
793
            [[
794
                'should' => 'Should mirror transform : rotateZ',
795
                'expected' => 'div { transform: rotateZ(-45.75deg); }',
796
                'input' => 'div { transform: rotateZ(45.75deg); }',
797
                'reversable' => true,
798
                'skip' => true
799
            ]],
800
            [[
801
                'should' => 'Should mirror transform (with no digits before dot): rotateZ',
802
                'expected' => 'div { transform: rotateZ(-0.75deg); }',
803
                'input' => 'div { transform: rotateZ(.75deg); }',
804
                'reversable' => false,
805
                'skip' => true
806
            ]],
807
            [[
808
                'should' => 'Should mirror transform with calc: rotateZ',
809
                'expected' => 'div { transform: rotateZ(-ms-calc(-1*(((25%/2) * 10deg)))); }',
810
                'input' => 'div { transform: rotateZ(-ms-calc(((25%/2) * 10deg))); }',
811
                'reversable' => false,
812
                'skip' => true
813
            ]],
814
            [[
815
                'should' => 'Should mirror transform : skew',
816
                'expected' => 'div { transform: skew(-20.25rad,-30deg); }',
817
                'input' => 'div { transform: skew(20.25rad,30deg); }',
818
                'reversable' => true,
819
                'skip' => true
820
            ]],
821
            [[
822
                'should' => 'Should mirror transform (with no digits before dot): skew',
823
                'expected' => 'div { transform: skew(-0.25rad,-30deg); }',
824
                'input' => 'div { transform: skew(.25rad,30deg); }',
825
                'reversable' => false,
826
                'skip' => true
827
            ]],
828
            [[
829
                'should' => 'Should mirror transform with calc: skew',
830
                'expected' => 'div { transform: skew(calc(-1*(((25%/2) * 10rad))),calc(-1*(((25%/2) * 10deg)))); }',
831
                'input' => 'div { transform: skew(calc(((25%/2) * 10rad)),calc(((25%/2) * 10deg))); }',
832
                'reversable' => false,
833
                'skip' => true
834
            ]],
835
            [[
836
                'should' => 'Should mirror transform : skewX',
837
                'expected' => 'div { transform: skewX(-20.75rad); }',
838
                'input' => 'div { transform: skewX(20.75rad); }',
839
                'reversable' => true,
840
                'skip' => true
841
            ]],
842
            [[
843
                'should' => 'Should mirror transform (with no digits before dot): skewX',
844
                'expected' => 'div { transform: skewX(-0.75rad); }',
845
                'input' => 'div { transform: skewX(.75rad); }',
846
                'reversable' => false,
847
                'skip' => true
848
            ]],
849
            [[
850
                'should' => 'Should mirror transform with calc: skewX',
851
                'expected' => 'div { transform: skewX(-moz-calc(-1*(((25%/2) * 10rad)))); }',
852
                'input' => 'div { transform: skewX(-moz-calc(((25%/2) * 10rad))); }',
853
                'reversable' => false,
854
                'skip' => true
855
            ]],
856
            [[
857
                'should' => 'Should mirror transform : skewY',
858
                'expected' => 'div { transform: skewY(-10.75grad); }',
859
                'input' => 'div { transform: skewY(10.75grad); }',
860
                'reversable' => true,
861
                'skip' => true
862
            ]],
863
            [[
864
                'should' => 'Should mirror transform (with no digits before dot): skewY',
865
                'expected' => 'div { transform: skewY(-0.75grad); }',
866
                'input' => 'div { transform: skewY(.75grad); }',
867
                'reversable' => false,
868
                'skip' => true
869
            ]],
870
            [[
871
                'should' => 'Should mirror transform with calc: skewY',
872
                'expected' => 'div { transform: skewY(calc(-1*(((25%/2) * 10grad)))); }',
873
                'input' => 'div { transform: skewY(calc(((25%/2) * 10grad))); }',
874
                'reversable' => false,
875
                'skip' => true
876
            ]],
877
            [[
878
                'should' => 'Should mirror multiple transforms : translateX translateY Rotate',
879
                'expected' => 'div { transform: translateX(-50.25px) translateY(50.25px) rotate(-20.75deg); }',
880
                'input' => 'div { transform: translateX(50.25px) translateY(50.25px) rotate(20.75deg); }',
881
                'reversable' => true,
882
                'skip' => true
883
            ]],
884
            [[
885
                'should' => 'Should mirror multiple transforms with calc : translateX translateY Rotate',
886
                'expected' => 'div { transform: translateX(-ms-calc(-1*(((25%/2) * 10px)))) translateY(-moz-calc(((25%/2) * 10rad))) rotate(calc(-1*(((25%/2) * 10grad)))); }',
887
                'input' => 'div { transform: translateX(-ms-calc(((25%/2) * 10px))) translateY(-moz-calc(((25%/2) * 10rad))) rotate(calc(((25%/2) * 10grad))); }',
888
                'reversable' => false,
889
                'skip' => true
890
            ]]
891
            */
892
        ];
893
    }
894
 
895
    /**
896
     * Data provider.
897
     * @return array
898
     */
899
    public function values_nsyntax_provider() {
900
        return [
901
            [[
902
                'should' => 'Should mirror property value: border-radius (4 values)',
903
                'expected' => 'div { border-radius: 40.25px 10.5px 10.75px 40.3px; }',
904
                'input' => 'div { border-radius: 10.5px 40.25px 40.3px 10.75px; }',
905
                'reversable' => true
906
            ]],
907
            [[
908
                'should' => 'Should mirror property value: border-radius (3 values)',
909
                'expected' => 'div { border-radius: 40.75px 10.75px 40.75px 40.3px; }',
910
                'input' => 'div { border-radius: 10.75px 40.75px 40.3px; }',
911
                'reversable' => false
912
            ]],
913
            [[
914
                'should' => 'Should mirror property value: border-radius (2 values)',
915
                'expected' => 'div { border-radius: 40.25px 10.75px; }',
916
                'input' => 'div { border-radius: 10.75px 40.25px; }',
917
                'reversable' => true
918
            ]],
919
            /* Not supported by MoodleHQ/RTLCSS yet.
920
            [[
921
                'should' => 'Should mirror property value: border-radius (4 values - double)',
922
                'expected' => 'div { border-radius: 40.25px 10.75px .5px 40.75px / .4em 1em 1em 4.5em; }',
923
                'input' => 'div { border-radius: 10.75px 40.25px 40.75px .5px / 1em .4em 4.5em 1em; }',
924
                'reversable' => true,
925
                'skip' => true
926
            ]],
927
            [[
928
                'should' => 'Should mirror property value: border-radius (3 values - double)',
929
                'expected' => 'div { border-radius: .40px 10.5px .40px 40px / 4em 1em 4em 3em; }',
930
                'input' => 'div { border-radius: 10.5px .40px 40px / 1em 4em 3em; }',
931
                'reversable' => false,
932
                'skip' => true
933
            ]],
934
            [[
935
                'should' => 'Should mirror property value: border-radius (2 values- double)',
936
                'expected' => 'div { border-radius: 40px 10px / 2.5em .75em; }',
937
                'input' => 'div { border-radius: 10px 40px / .75em 2.5em; }',
938
                'reversable' => true,
939
                'skip' => true
940
            ]],
941
            */
942
            [[
943
                'should' => 'Should mirror property value: border-width',
944
                'expected' => 'div { border-width: 1px 4px .3em 2.5em; }',
945
                'input' => 'div { border-width: 1px 2.5em .3em 4px; }',
946
                'reversable' => true
947
            ]],
948
            [[
949
                'should' => 'Should mirror property value: border-width (none length)',
950
                'expected' => 'div { border-width: thin medium thick none; }',
951
                'input' => 'div { border-width: thin none thick medium; }',
952
                'reversable' => true
953
            ]],
954
            [[
955
                'should' => 'Should mirror property value: border-style (4 values)',
956
                'expected' => 'div { border-style: none dashed dotted solid; }',
957
                'input' => 'div { border-style: none solid dotted dashed; }',
958
                'reversable' => true
959
            ]],
960
            [[
961
                'should' => 'Should mirror property value: border-color (4 values)',
962
                'expected' => 'div { border-color: rgba(255, 255, 255, 1) rgb(0, 0, 0) rgb(0, 0, 0) hsla(0, 100%, 50%, 1); }',
963
                'input' => 'div { border-color: rgba(255, 255, 255, 1) hsla(0, 100%, 50%, 1) rgb(0, 0, 0) rgb(0, 0, 0); }',
964
                'reversable' => true
965
            ]],
966
            [[
967
                'should' => 'Should not mirror property value: border-color (3 values)',
968
                'expected' => 'div { border-color: rgb(0, 0, 0) rgb(0, 0, 0) hsla(0, 100%, 50%, 1); }',
969
                'input' => 'div { border-color: #000 rgb(0, 0, 0) hsla(0, 100%, 50%, 1); }',
970
                'reversable' => false
971
            ]],
972
            [[
973
                'should' => 'Should not mirror property value: border-color (2 values)',
974
                'expected' => 'div { border-color: rgb(0, 0, 0) hsla(0, 100%, 50%, 1); }',
975
                'input' => 'div { border-color: rgb(0, 0, 0) hsla(0, 100%, 50%, 1); }',
976
                'reversable' => false
977
            ]],
978
            [[
979
                'should' => 'Should mirror property value: margin',
980
                'expected' => 'div { margin: .1em auto 3.5rem 2px; }',
981
                'input' => 'div { margin: .1em 2px 3.5rem auto; }',
982
                'reversable' => true
983
            ]],
984
            [[
985
                'should' => 'Should mirror property value: padding',
986
                'expected' => 'div { padding: 1px 4px .3rem 2.5em; }',
987
                'input' => 'div { padding: 1px 2.5em .3rem 4px; }',
988
                'reversable' => true
989
            ]],
990
            /* Not supported by MoodleHQ/RTLCSS yet.
991
            [[
992
                'should' => 'Should mirror property value: box-shadow',
993
                'expected' => 'div { box-shadow: -60px -16px rgba(0, 128, 128, 0.98), -10.25px 5px 5px #ff0, inset -0.5em 1em 0 white; }',
994
                'input' => 'div { box-shadow: 60px -16px rgba(0, 128, 128, 0.98), 10.25px 5px 5px #ff0, inset 0.5em 1em 0 white; }',
995
                'reversable' => true,
996
                'skip' => true
997
            ]],
998
            [[
999
                'should' => 'Should mirror property value: text-shadow',
1000
                'expected' => 'div { text-shadow: -60px -16px rgba(0, 128, 128, 0.98), -10.25px 5px 5px #ff0, inset -0.5em 1em 0 white; }',
1001
                'input' => 'div { text-shadow: 60px -16px rgba(0, 128, 128, 0.98), 10.25px 5px 5px #ff0, inset 0.5em 1em 0 white; }',
1002
                'reversable' => true,
1003
                'skip' => true
1004
            ]],
1005
            [[
1006
                'should' => 'Should mirror property value (no digit before the dot): box-shadow, text-shadow',
1007
                'expected' => 'div { box-shadow: inset -0.5em 1em 0 white; text-shadow: inset -0.5em 1em 0 white; }',
1008
                'input' => 'div { box-shadow: inset .5em 1em 0 white; text-shadow: inset .5em 1em 0 white; }',
1009
                'reversable' => false,
1010
                'skip' => true
1011
            ]]
1012
            */
1013
        ];
1014
    }
1015
 
1016
    /**
1017
     * Data provider.
1018
     * @return array
1019
     */
1020
    public function values_provider() {
1021
        return [
1022
            [[
1023
                'should' => 'Should mirror property value: clear',
1024
                'expected' => 'div { clear:right; }',
1025
                'input' => 'div { clear:left; }',
1026
                'reversable' => true
1027
            ]],
1028
            [[
1029
                'should' => 'Should mirror property value: direction',
1030
                'expected' => 'div { direction:ltr; }',
1031
                'input' => 'div { direction:rtl; }',
1032
                'reversable' => true
1033
            ]],
1034
            [[
1035
                'should' => 'Should mirror property value: float',
1036
                'expected' => 'div { float:right; }',
1037
                'input' => 'div { float:left; }',
1038
                'reversable' => true
1039
            ]],
1040
            [[
1041
                'should' => 'Should mirror property value: text-align',
1042
                'expected' => 'div { text-align:right; }',
1043
                'input' => 'div { text-align:left; }',
1044
                'reversable' => true
1045
            ]],
1046
            [[
1047
                'should' => 'Should mirror property value: cursor nw',
1048
                'expected' => 'div { cursor:nw-resize; }',
1049
                'input' => 'div { cursor:ne-resize; }',
1050
                'reversable' => true
1051
            ]],
1052
            [[
1053
                'should' => 'Should mirror property value: cursor sw',
1054
                'expected' => 'div { cursor:sw-resize; }',
1055
                'input' => 'div { cursor:se-resize; }',
1056
                'reversable' => true
1057
            ]],
1058
            [[
1059
                'should' => 'Should mirror property value: cursor nesw',
1060
                'expected' => 'div { cursor:nesw-resize; }',
1061
                'input' => 'div { cursor:nwse-resize; }',
1062
                'reversable' => true
1063
            ]],
1064
            [[
1065
                'should' => 'Should keep property value as is: cursor ew',
1066
                'expected' => 'div { cursor:ew-resize; }',
1067
                'input' => 'div { cursor:ew-resize; }',
1068
                'reversable' => false
1069
            ]],
1070
            /* Not supported by MoodleHQ/RTLCSS yet.
1071
            [[
1072
                'should' => 'Should process string map in url: cursor (processUrls: true)',
1073
                'expected' => '.foo { cursor: url(right.cur), url(rtl.cur), se-resize, auto }',
1074
                'input' => '.foo { cursor: url(left.cur), url(ltr.cur), sw-resize, auto }',
1075
                'reversable' => true,
1076
                'options' => [ 'processUrls' => true ],
1077
                'skip' => true
1078
            ]],
1079
            */
1080
            [[
1081
                'should' => 'Should mirror property value: transition',
1082
                'expected' => '.foo { transition:right .3s ease .1s,left .3s ease .1s,margin-right .3s ease,margin-left .3s ease,padding-right .3s ease,padding-left .3s ease; }',
1083
                'input' => '.foo { transition:left .3s ease .1s,right .3s ease .1s,margin-left .3s ease,margin-right .3s ease,padding-left .3s ease,padding-right .3s ease; }',
1084
                'reversable' => true
1085
            ]],
1086
            [[
1087
                'should' => 'Should mirror property value: transition-property',
1088
                'expected' => '.foo { transition-property:right; }',
1089
                'input' => '.foo { transition-property:left; }',
1090
                'reversable' => true
1091
            ]]
1092
        ];
1093
    }
1094
 
1095
    /**
1096
     * Assert that the provided data flips.
1097
     *
1098
     * @param string $expected The expected output.
1099
     * @param string $input The input.
1100
     * @param string $description The description of the assertion.
1101
     * @param OutputFormat $output The output format to use.
1102
     */
1103
    protected function assert_flips($expected, $input, $description, $output = null) {
1104
        $parser = new Parser($input);
1105
        $tree = $parser->parse();
1106
        $rtlcss = new core_rtlcss($tree);
1107
        $flipped = $rtlcss->flip();
1108
        $this->assertEquals($expected, $flipped->render($output), $description);
1109
    }
1110
 
1111
    /**
1112
     * Assert data.
1113
     *
1114
     * @param array $data With the keys: 'input', 'expected', 'reversable', 'should', and 'skip'.
1115
     * @param OutputFormat $output The output format to use.
1116
     */
1117
    protected function assert_sample($data, $output = null) {
1118
        if (!empty($data['skip'])) {
1119
            $this->markTestSkipped('Not yet supported!');
1120
        }
1121
        $this->assert_flips($data['expected'], $data['input'], $data['should'], $output);
1122
        if (!empty($data['reversable'])) {
1123
            $this->assert_flips($data['input'], $data['expected'], $data['should'] . ' (reversed)', $output);
1124
        }
1125
    }
1126
 
1127
    /**
1128
     * Test background images.
1129
     * @param array $data the provider data.
1130
     * @dataProvider background_image_provider
1131
     */
11 efrain 1132
    public function test_background_image($data): void {
1 efrain 1133
        $this->markTestSkipped('Not yet supported!');
1134
        $output = new OutputFormat();
1135
        $this->assert_sample($data, $output);
1136
    }
1137
 
1138
    /**
1139
     * Test background position.
1140
     * @param array $data the provider data.
1141
     * @dataProvider background_position_provider
1142
     */
11 efrain 1143
    public function test_background_position($data): void {
1 efrain 1144
        $output = new OutputFormat();
1145
        $output->set('SpaceAfterRuleName', '');
1146
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1147
        $this->assert_sample($data, $output);
1148
    }
1149
 
1150
    /**
1151
     * Test background.
1152
     * @param array $data the provider data.
1153
     * @dataProvider background_provider
1154
     */
11 efrain 1155
    public function test_background($data): void {
1 efrain 1156
        $output = new OutputFormat();
1157
        $output->set('SpaceAfterRuleName', ' ');
1158
        $output->set('SpaceBeforeRules', ' ');
1159
        $output->set('SpaceAfterRules', ' ');
1160
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1161
        $this->assert_sample($data, $output);
1162
    }
1163
 
1164
    /**
1165
     * Test directives.
1166
     * @param array $data the provider data.
1167
     * @dataProvider directives_provider
1168
     */
11 efrain 1169
    public function test_directives($data): void {
1 efrain 1170
        $output = new OutputFormat();
1171
        $output->set('SpaceAfterRuleName', '');
1172
        $output->set('SpaceBeforeRules', '');
1173
        $output->set('SpaceAfterRules', '');
1174
        $output->set('SpaceBetweenRules', '');
1175
        $output->set('SpaceBetweenBlocks', ' ');
1176
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1177
        $this->assert_sample($data, $output);
1178
    }
1179
 
1180
    /**
1181
     * Test properties.
1182
     * @param array $data the provider data.
1183
     * @dataProvider properties_provider
1184
     */
11 efrain 1185
    public function test_properties($data): void {
1 efrain 1186
        $output = new OutputFormat();
1187
        $output->set('SpaceAfterRuleName', '');
1188
        $output->set('SpaceBeforeRules', ' ');
1189
        $output->set('SpaceAfterRules', ' ');
1190
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1191
        $this->assert_sample($data, $output);
1192
    }
1193
 
1194
    /**
1195
     * Test special.
1196
     * @param array $data the provider data.
1197
     * @dataProvider special_provider
1198
     */
11 efrain 1199
    public function test_special($data): void {
1 efrain 1200
        $this->markTestSkipped('Not yet supported!');
1201
        $output = new OutputFormat();
1202
        $output->set('SpaceBeforeRules', ' ');
1203
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1204
        $this->assert_sample($data, $output);
1205
    }
1206
 
1207
    /**
1208
     * Test transform original.
1209
     * @param array $data the provider data.
1210
     * @dataProvider transform_origin_provider
1211
     */
11 efrain 1212
    public function test_transform_origin($data): void {
1 efrain 1213
        $output = new OutputFormat();
1214
        $output->set('SpaceAfterRuleName', '');
1215
        $output->set('SpaceBeforeRules', ' ');
1216
        $output->set('SpaceAfterRules', ' ');
1217
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1218
        $this->assert_sample($data, $output);
1219
    }
1220
 
1221
 
1222
    /**
1223
     * Test transform.
1224
     * @param array $data the provider data.
1225
     * @dataProvider transforms_provider
1226
     */
11 efrain 1227
    public function test_transforms($data): void {
1 efrain 1228
        $this->markTestSkipped('Not yet supported!');
1229
        $output = new OutputFormat();
1230
        $output->set('SpaceBeforeRules', ' ');
1231
        $output->set('SpaceAfterRules', ' ');
1232
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1233
        $this->assert_sample($data, $output);
1234
    }
1235
 
1236
    /**
1237
     * Test values n-syntax.
1238
     * @param array $data the provider data.
1239
     * @dataProvider values_nsyntax_provider
1240
     */
11 efrain 1241
    public function test_values_nsyntax($data): void {
1 efrain 1242
        $output = new OutputFormat();
1243
        $output->set('SpaceBeforeRules', ' ');
1244
        $output->set('SpaceAfterRules', ' ');
1245
        $output->set('RGBHashNotation', false);
1246
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1247
        $this->assert_sample($data, $output);
1248
    }
1249
 
1250
    /**
1251
     * Test values.
1252
     * @param array $data the provider data.
1253
     * @dataProvider values_provider
1254
     */
11 efrain 1255
    public function test_values($data): void {
1 efrain 1256
        $output = new OutputFormat();
1257
        $output->set('SpaceAfterRuleName', '');
1258
        $output->set('SpaceBeforeRules', ' ');
1259
        $output->set('SpaceAfterRules', ' ');
1260
        $output->set('SpaceAfterListArgumentSeparator', array('default' => '', ',' => ' '));
1261
        $this->assert_sample($data, $output);
1262
    }
1263
}