@@ -50,6 +50,48 @@ public function testAsciiClosureRule()
5050 $ this ->assertSame ('Dieser Wert sollte grOEsser oder gleich ' , (string ) $ s ->ascii ([$ rule ]));
5151 }
5252
53+ /**
54+ * @dataProvider provideLocaleLower
55+ *
56+ * @requires extension intl
57+ */
58+ public function testLocaleLower (string $ locale , string $ expected , string $ origin )
59+ {
60+ $ instance = static ::createFromString ($ origin )->localeLower ($ locale );
61+
62+ $ this ->assertNotSame (static ::createFromString ($ origin ), $ instance );
63+ $ this ->assertEquals (static ::createFromString ($ expected ), $ instance );
64+ $ this ->assertSame ($ expected , (string ) $ instance );
65+ }
66+
67+ /**
68+ * @dataProvider provideLocaleUpper
69+ *
70+ * @requires extension intl
71+ */
72+ public function testLocaleUpper (string $ locale , string $ expected , string $ origin )
73+ {
74+ $ instance = static ::createFromString ($ origin )->localeUpper ($ locale );
75+
76+ $ this ->assertNotSame (static ::createFromString ($ origin ), $ instance );
77+ $ this ->assertEquals (static ::createFromString ($ expected ), $ instance );
78+ $ this ->assertSame ($ expected , (string ) $ instance );
79+ }
80+
81+ /**
82+ * @dataProvider provideLocaleTitle
83+ *
84+ * @requires extension intl
85+ */
86+ public function testLocaleTitle (string $ locale , string $ expected , string $ origin )
87+ {
88+ $ instance = static ::createFromString ($ origin )->localeTitle ($ locale );
89+
90+ $ this ->assertNotSame (static ::createFromString ($ origin ), $ instance );
91+ $ this ->assertEquals (static ::createFromString ($ expected ), $ instance );
92+ $ this ->assertSame ($ expected , (string ) $ instance );
93+ }
94+
5395 public function provideCreateFromCodePoint (): array
5496 {
5597 return [
@@ -291,6 +333,78 @@ public static function provideLower(): array
291333 );
292334 }
293335
336+ public static function provideLocaleLower (): array
337+ {
338+ return [
339+ // Lithuanian
340+ // Introduce an explicit dot above when lowercasing capital I's and J's
341+ // whenever there are more accents above.
342+ // LATIN CAPITAL LETTER I WITH OGONEK -> LATIN SMALL LETTER I WITH OGONEK
343+ ['lt ' , 'į ' , 'Į ' ],
344+ // LATIN CAPITAL LETTER I WITH GRAVE -> LATIN SMALL LETTER I COMBINING DOT ABOVE
345+ ['lt ' , 'i̇̀ ' , 'Ì ' ],
346+ // LATIN CAPITAL LETTER I WITH ACUTE -> LATIN SMALL LETTER I COMBINING DOT ABOVE COMBINING ACUTE ACCENT
347+ ['lt ' , 'i̇́ ' , 'Í ' ],
348+ // LATIN CAPITAL LETTER I WITH TILDE -> LATIN SMALL LETTER I COMBINING DOT ABOVE COMBINING TILDE
349+ ['lt ' , 'i̇̃ ' , 'Ĩ ' ],
350+
351+ // Turkish and Azeri
352+ // When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into 'i'.
353+ // LATIN CAPITAL LETTER I WITH DOT ABOVE -> LATIN SMALL LETTER I
354+ ['tr ' , 'i ' , 'İ ' ],
355+ ['tr_TR ' , 'i ' , 'İ ' ],
356+ ['az ' , 'i ' , 'İ ' ],
357+
358+ // Default casing rules
359+ // LATIN CAPITAL LETTER I WITH DOT ABOVE -> LATIN SMALL LETTER I COMBINING DOT ABOVE
360+ ['en_US ' , 'i̇ ' , 'İ ' ],
361+ ['en ' , 'i̇ ' , 'İ ' ],
362+ ];
363+ }
364+
365+ public static function provideLocaleUpper (): array
366+ {
367+ return [
368+ // Turkish and Azeri
369+ // When uppercasing, i turns into a dotted capital I
370+ // LATIN SMALL LETTER I -> LATIN CAPITAL LETTER I WITH DOT ABOVE
371+ ['tr ' , 'İ ' , 'i ' ],
372+ ['tr_TR ' , 'İ ' , 'i ' ],
373+ ['az ' , 'İ ' , 'i ' ],
374+
375+ // Greek
376+ // Remove accents when uppercasing
377+ // GREEK SMALL LETTER ALPHA WITH TONOS -> GREEK CAPITAL LETTER ALPHA
378+ ['el ' , 'Α ' , 'ά ' ],
379+ ['el_GR ' , 'Α ' , 'ά ' ],
380+
381+ // Default casing rules
382+ // GREEK SMALL LETTER ALPHA WITH TONOS -> GREEK CAPITAL LETTER ALPHA WITH TONOS
383+ ['en_US ' , 'Ά ' , 'ά ' ],
384+ ['en ' , 'Ά ' , 'ά ' ],
385+ ];
386+ }
387+
388+ public static function provideLocaleTitle (): array
389+ {
390+ return [
391+ // Greek
392+ // Titlecasing words, should keep the accents on the first letter
393+ ['el ' , 'Άδικος ' , 'άδικος ' ],
394+ ['el_GR ' , 'Άδικος ' , 'άδικος ' ],
395+ ['en ' , 'Άδικος ' , 'άδικος ' ],
396+
397+ // Dutch
398+ // Title casing should treat 'ij' as one character
399+ ['nl_NL ' , 'IJssel ' , 'ijssel ' ],
400+ ['nl_BE ' , 'IJssel ' , 'ijssel ' ],
401+ ['nl ' , 'IJssel ' , 'ijssel ' ],
402+
403+ // Default casing rules
404+ ['en ' , 'Ijssel ' , 'ijssel ' ],
405+ ];
406+ }
407+
294408 public static function provideUpper (): array
295409 {
296410 return array_merge (
0 commit comments