1 <?php
2 
3 /**
4  * Hoa
5  *
6  *
7  * @license
8  *
9  * New BSD License
10  *
11  * Copyright © 2007-2017, Hoa community. All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *     * Redistributions of source code must retain the above copyright
16  *       notice, this list of conditions and the following disclaimer.
17  *     * Redistributions in binary form must reproduce the above copyright
18  *       notice, this list of conditions and the following disclaimer in the
19  *       documentation and/or other materials provided with the distribution.
20  *     * Neither the name of the Hoa nor the names of its contributors may be
21  *       used to endorse or promote products derived from this software without
22  *       specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 namespace Hoa\Ustring\Test\Unit;
38 
39 use Hoa\Test;
40 use Hoa\Ustring as LUT;
41 
42 /**
43  * Class \Hoa\Ustring\Test\Unit\Ustring.
44  *
45  * Test suite of the string class.
46  *
47  * @copyright  Copyright © 2007-2017 Hoa community
48  * @license    New BSD License
49  */
50 class Ustring extends Test\Unit\Suite
51 {
52     public function case_check_mbstring()
53     {
54         $this
55             ->given($this->function->function_exists = true)
56             ->then
57                 ->boolean(LUT::checkMbString())
58                     ->isTrue();
59     }
60 
61     public function case_check_no_mbstring()
62     {
63         $this
64             ->given(
65                 $this->function->function_exists = function ($name) {
66                     return 'mb_substr' !== $name;
67                 }
68             )
69             ->exception(function () {
70                 new LUT();
71             })
72                 ->isInstanceOf('Hoa\Ustring\Exception');
73     }
74 
75     public function case_append_ltr()
76     {
77         $this
78             ->given($string = new LUT('je'))
79             ->when($result = $string->append(' t\'aime'))
80             ->then
81                 ->object($result)
82                     ->isIdenticalTo($string)
83                 ->string((string) $result)
84                     ->isEqualTo('je t\'aime');
85     }
86 
87     public function case_append_rtl()
88     {
89         $this
90             ->given($string = new LUT('أ'))
91             ->when($result = $string->append('حبك'))
92             ->then
93                 ->object($result)
94                     ->isIdenticalTo($string)
95                 ->string((string) $result)
96                     ->isEqualTo('أحبك');
97     }
98 
99     public function case_prepend_ltr()
100     {
101         $this
102             ->given($string = new LUT(' t\'aime'))
103             ->when($result = $string->prepend('je'))
104             ->then
105                 ->object($result)
106                     ->isIdenticalTo($string)
107                 ->string((string) $result)
108                     ->isEqualTo('je t\'aime');
109     }
110 
111     public function case_prepend_rtl()
112     {
113         $this
114             ->given($string = new LUT('ك'))
115             ->when($result = $string->prepend('أحب'))
116             ->then
117                 ->object($result)
118                     ->isIdenticalTo($string)
119                 ->string((string) $result)
120                     ->isEqualTo('أحبك');
121     }
122 
123     public function case_pad_beginning_ltr()
124     {
125         $this
126             ->given($string = new LUT('je t\'aime'))
127             ->when($result = $string->pad(20, '�� �� �� ❤️ ', LUT::BEGINNING))
128             ->then
129                 ->object($result)
130                     ->isIdenticalTo($string)
131                 ->string((string) $result)
132                     ->isEqualTo('�� �� �� ❤️ �� je t\'aime');
133     }
134 
135     public function case_pad_beginning_rtl()
136     {
137         $this
138             ->given($string = new LUT('أحبك'))
139             ->when($result = $string->pad(20, '�� �� �� ❤️ ', LUT::BEGINNING))
140             ->then
141                 ->object($result)
142                     ->isIdenticalTo($string)
143                 ->string((string) $result)
144                     ->isEqualTo('�� �� �� ❤️ �� �� �� ❤أحبك');
145     }
146 
147     public function case_pad_end_ltr()
148     {
149         $this
150             ->given($string = new LUT('je t\'aime'))
151             ->when($result = $string->pad(20, '�� �� �� ❤️ ', LUT::END))
152             ->then
153                 ->object($result)
154                     ->isIdenticalTo($string)
155                 ->string((string) $result)
156                     ->isEqualTo('je t\'aime�� �� �� ❤️ �� ');
157     }
158 
159     public function case_pad_end_rtl()
160     {
161         $this
162             ->given($string = new LUT('أحبك'))
163             ->when($result = $string->pad(20, '�� �� �� ❤️ ', LUT::END))
164             ->then
165                 ->object($result)
166                     ->isIdenticalTo($string)
167                 ->string((string) $result)
168                     ->isEqualTo('أحبك�� �� �� ❤️ �� �� �� ❤');
169     }
170 
171     public function case_compare_no_collator()
172     {
173         $this
174             ->given(
175                 $this->function->class_exists = function ($name) {
176                     return 'Collator' !== $name;
177                 },
178                 $string = new LUT('b')
179             )
180             ->case_compare();
181     }
182 
183     public function case_compare()
184     {
185         $this
186             ->given($string = new LUT('b'))
187             ->when($result = $string->compare('a'))
188             ->then
189                 ->integer($result)
190                     ->isEqualTo(1)
191 
192             ->when($result = $string->compare('b'))
193             ->then
194                 ->integer($result)
195                     ->isEqualTo(0)
196 
197             ->when($result = $string->compare('c'))
198             ->then
199                 ->integer($result)
200                     ->isEqualTo(-1);
201     }
202 
203     public function case_collator()
204     {
205         $this
206             ->given(
207                 $this->function->setlocale = 'fr_FR',
208                 $collator = LUT::getCollator()
209             )
210             ->when($result = $collator->getLocale(\Locale::VALID_LOCALE))
211             ->then
212                 ->string($result)
213                     ->isEqualTo('fr');
214     }
215 
216     public function case_safe_unsafe_pattern()
217     {
218         $this
219             ->given($pattern = '/foo/i')
220             ->when($result = LUT::safePattern($pattern))
221             ->then
222                 ->string($result)
223                     ->isEqualto('/foo/iu');
224     }
225 
226     public function case_safe_safe_pattern()
227     {
228         $this
229             ->given($pattern = '/foo/ui')
230             ->when($result = LUT::safePattern($pattern))
231             ->then
232                 ->string($result)
233                     ->isEqualto('/foo/ui');
234     }
235 
236     public function case_match_default()
237     {
238         $this
239             ->given(
240                 $pattern = '/��/u',
241                 $string  = new LUT('foo �� bar')
242             )
243             ->when($result = $string->match($pattern, $matches))
244             ->then
245                 ->integer($result)
246                     ->isEqualTo(1)
247                 ->array($matches)
248                     ->isEqualTo([
249                         0 => '��'
250                     ]);
251     }
252 
253     public function case_match_offset()
254     {
255         $this
256             ->given(
257                 $pattern = '/��/u',
258                 $string  = new LUT('foo �� bar')
259             )
260             ->when($result = $string->match($pattern, $matches, 0, 0))
261             ->then
262                 ->integer($result)
263                     ->isEqualTo(1)
264                 ->array($matches)
265                     ->isEqualTo([0 => '��'])
266 
267             ->when($result = $string->match($pattern, $matches, 0, 4))
268             ->then
269                 ->integer($result)
270                     ->isEqualTo(1)
271                 ->array($matches)
272                     ->isEqualTo([0 => '��'])
273 
274             ->when($result = $string->match($pattern, $matches, 0, 5))
275             ->then
276                 ->integer($result)
277                     ->isEqualTo(0)
278                 ->array($matches)
279                     ->isEmpty();
280     }
281 
282     public function case_match_with_offset()
283     {
284         $this
285             ->given(
286                 $pattern = '/��/u',
287                 $string  = new LUT('foo �� bar')
288             )
289             ->when($result = $string->match($pattern, $matches, $string::WITH_OFFSET))
290             ->then
291                 ->integer($result)
292                     ->isEqualTo(1)
293                 ->array($matches)
294                     ->isEqualTo([
295                         0 => [
296                             0 => '��',
297                             1 => 4
298                         ]
299                     ]);
300     }
301 
302     public function case_match_all_default()
303     {
304         $this
305             ->given(
306                 $pattern = '/��/u',
307                 $string  = new LUT('foo �� bar �� baz')
308             )
309             ->when($result = $string->match($pattern, $matches, 0, 0, true))
310             ->then
311                 ->integer($result)
312                     ->isEqualTo(2)
313                 ->array($matches)
314                     ->isEqualTo([
315                         0 => [
316                             0 => '��',
317                             1 => '��'
318                         ]
319                     ]);
320     }
321 
322     public function case_match_all_with_offset()
323     {
324         $this
325             ->given(
326                 $pattern = '/��/u',
327                 $string  = new LUT('foo �� bar �� baz')
328             )
329             ->when($result = $string->match($pattern, $matches, $string::WITH_OFFSET, 0, true))
330             ->then
331                 ->integer($result)
332                     ->isEqualTo(2)
333                 ->array($matches)
334                     ->isEqualTo([
335                         0 => [
336                             0 => [
337                                 0 => '��',
338                                 1 => 4
339                             ],
340                             1 => [
341                                 0 => '��',
342                                 1 => 13
343                             ]
344                         ]
345                     ]);
346     }
347 
348     public function case_match_all_grouped_by_pattern()
349     {
350         $this
351             ->given(
352                 $pattern = '/(��)/u',
353                 $string  = new LUT('foo �� bar �� baz')
354             )
355             ->when($result = $string->match($pattern, $matches, $string::GROUP_BY_PATTERN, 0, true))
356             ->then
357                 ->integer($result)
358                     ->isEqualTo(2)
359                 ->array($matches)
360                     ->isEqualTo([
361                         0 => [
362                             0 => '��',
363                             1 => '��'
364                         ],
365                         1 => [
366                             0 => '��',
367                             1 => '��'
368                         ]
369                     ]);
370     }
371 
372     public function case_match_all_grouped_by_tuple()
373     {
374         $this
375             ->given(
376                 $pattern = '/(��)/u',
377                 $string  = new LUT('foo �� bar �� baz')
378             )
379             ->when($result = $string->match($pattern, $matches, $string::GROUP_BY_TUPLE, 0, true))
380             ->then
381                 ->integer($result)
382                     ->isEqualTo(2)
383                 ->array($matches)
384                     ->isEqualTo([
385                         0 => [
386                             0 => '��',
387                             1 => '��'
388                         ],
389                         1 => [
390                             0 => '��',
391                             1 => '��'
392                         ]
393                     ]);
394     }
395 
396     public function case_replace()
397     {
398         $this
399             ->given($string = new LUT('❤️ �� ��'))
400             ->when($result = $string->replace('/��/u', '��'))
401             ->then
402                 ->object($result)
403                     ->isIdenticalTo($string)
404                 ->string((string) $result)
405                     ->isEqualTo('❤️ �� ��');
406     }
407 
408     public function case_replace_limited()
409     {
410         $this
411             ->given($string = new LUT('❤️ �� ��'))
412             ->when($result = $string->replace('/��/u', '��', 1))
413             ->then
414                 ->object($result)
415                     ->isIdenticalTo($string)
416                 ->string((string) $result)
417                     ->isEqualTo('❤️ �� ��');
418     }
419 
420     public function case_split_default()
421     {
422         $this
423             ->given($string = new LUT('❤️��❤️��❤️'))
424             ->when($result = $string->split('/��/'))
425             ->then
426                 ->array($result)
427                     ->isEqualTo([
428                         0 => '❤️',
429                         1 => '❤️',
430                         2 => '❤️'
431                     ]);
432     }
433 
434     public function case_split_default_limited()
435     {
436         $this
437             ->given($string = new LUT('❤️��❤️��❤️'))
438             ->when($result = $string->split('/��/', 1))
439             ->then
440                 ->array($result)
441                     ->isEqualTo([
442                         0 => '❤️��❤️��❤️'
443                     ]);
444     }
445 
446     public function case_split_with_delimiters()
447     {
448         $this
449             ->given($string = new LUT('❤️��❤️��❤️'))
450             ->when($result = $string->split('/��/', -1, $string::WITH_DELIMITERS))
451             ->then
452                 ->array($result)
453                     ->isEqualTo([
454                         0 => '❤️',
455                         1 => '❤️',
456                         2 => '❤️'
457                     ]);
458     }
459 
460     public function case_split_with_offset()
461     {
462         $this
463             ->given($string = new LUT('❤️��❤️��❤️'))
464             ->when($result = $string->split('/��/', -1, $string::WITH_OFFSET))
465             ->then
466                 ->array($result)
467                     ->isEqualTo([
468                         0 => [
469                             0 => '❤️',
470                             1 => 0
471                         ],
472                         1 => [
473                             0 => '❤️',
474                             1 => 10
475                         ],
476                         2 => [
477                             0 => '❤️',
478                             1 => 20
479                         ]
480                     ]);
481     }
482 
483     public function case_iterator_ltr()
484     {
485         $this
486             ->given($string = new LUT('je t\'aime'))
487             ->when($result = iterator_to_array($string))
488             ->then
489                 ->array($result)
490                     ->isEqualTo([
491                         'j',
492                         'e',
493                         ' ',
494                         't',
495                         '\'',
496                         'a',
497                         'i',
498                         'm',
499                         'e'
500                     ]);
501     }
502 
503     public function case_iterator_rtl()
504     {
505         $this
506             ->given($string = new LUT('أحبك'))
507             ->when($result = iterator_to_array($string))
508             ->then
509                 ->array($result)
510                     ->isEqualTo([
511                         'أ',
512                         'ح',
513                         'ب',
514                         'ك'
515                     ]);
516     }
517 
518     public function case_to_lower()
519     {
520         $this
521             ->given($string = new LUT(\'ΑΓΑΠΏ'))
522             ->when($result = $string->toLowerCase())
523             ->then
524                 ->object($result)
525                     ->isIdenticalTo($string)
526                 ->string((string) $result)
527                     ->isEqualTo(\'αγαπώ')
528 
529             ->given($string = new LUT('JE T\'AIME'))
530             ->when($result = $string->toLowerCase())
531             ->then
532                 ->object($result)
533                     ->isIdenticalTo($string)
534                 ->string((string) $result)
535                     ->isEqualTo('je t\'aime');
536     }
537 
538     public function case_to_upper()
539     {
540         $this
541             ->given($string = new LUT(\'αγαπώ'))
542             ->when($result = $string->toUpperCase())
543             ->then
544                 ->object($result)
545                     ->isIdenticalTo($string)
546                 ->string((string) $result)
547                     ->isEqualTo(\'ΑΓΑΠΏ')
548 
549             ->given($string = new LUT('je t\'aime'))
550             ->when($result = $string->toUpperCase())
551             ->then
552                 ->object($result)
553                     ->isIdenticalTo($string)
554                 ->string((string) $result)
555                     ->isEqualTo('JE T\'AIME');
556     }
557 
558     public function case_trim_default()
559     {
560         $this
561             ->given($string = new LUT('����❤️����'))
562             ->when($result = $string->trim('��'))
563             ->then
564                 ->object($result)
565                     ->isIdenticalTo($string)
566                 ->string((string) $result)
567                     ->isEqualTo('❤️');
568     }
569 
570     public function case_trim_beginning()
571     {
572         $this
573             ->given($string = new LUT('����❤️����'))
574             ->when($result = $string->trim('��', $string::BEGINNING))
575             ->then
576                 ->object($result)
577                     ->isIdenticalTo($string)
578                 ->string((string) $result)
579                     ->isEqualTo('❤️����');
580     }
581 
582     public function case_trim_end()
583     {
584         $this
585             ->given($string = new LUT('����❤️����'))
586             ->when($result = $string->trim('��', $string::END))
587             ->then
588                 ->object($result)
589                     ->isIdenticalTo($string)
590                 ->string((string) $result)
591                     ->isEqualTo('����❤️');
592     }
593 
594     public function case_offset_get_ltr()
595     {
596         $this
597             ->given($string = new LUT('je t\'aime'))
598             ->when($result = $string[0])
599             ->then
600                 ->string($result)
601                     ->isEqualTo('j')
602 
603             ->when($result = $string[-1])
604             ->then
605                 ->string($result)
606                     ->isEqualTo('e');
607     }
608 
609     public function case_offset_get_rtl()
610     {
611         $this
612             ->given($string = new LUT('أحبك'))
613             ->when($result = $string[0])
614             ->then
615                 ->string($result)
616                     ->isEqualTo('أ')
617 
618             ->when($result = $string[-1])
619             ->then
620                 ->string($result)
621                     ->isEqualTo('ك');
622     }
623 
624     public function case_offset_set()
625     {
626         $this
627             ->given($string = new LUT('أحبﻙ'))
628             ->when($string[-1] = 'ك')
629             ->then
630                 ->string((string) $string)
631                     ->isEqualTo('أحبك');
632     }
633 
634     public function case_offset_unset()
635     {
636         $this
637             ->given($string = new LUT('أحبك��'))
638             ->when(function () use ($string) {
639                 unset($string[-1]);
640             })
641             ->then
642                 ->string((string) $string)
643                     ->isEqualTo('أحبك');
644     }
645 
646     public function case_reduce()
647     {
648         $this
649             ->given($string = new LUT('أحبك'))
650             ->when($result = $string->reduce(0, 1))
651             ->then
652                 ->object($result)
653                     ->isIdenticalTo($string)
654                 ->string((string) $result)
655                     ->isEqualTo('أ');
656     }
657 
658     public function case_count()
659     {
660         $this
661             ->given($string = new LUT('je t\'aime'))
662             ->when($result = count($string))
663             ->then
664                 ->integer($result)
665                     ->isEqualTo(9)
666 
667             ->given($string = new LUT('أحبك'))
668             ->when($result = count($string))
669             ->then
670                 ->integer($result)
671                     ->isEqualTo(4)
672 
673             ->given($string = new LUT('��'))
674             ->when($result = count($string))
675             ->then
676                 ->integer($result)
677                     ->isEqualTo(1);
678     }
679 
680     public function case_byte_at()
681     {
682         $this
683             ->given($string = new LUT('��'))
684             ->when($result = $string->getByteAt(0))
685             ->then
686                 ->integer(ord($result))
687                     ->isEqualTo(0xf0)
688 
689             ->when($result = $string->getByteAt(1))
690             ->then
691                 ->integer(ord($result))
692                     ->isEqualTo(0x9f)
693 
694             ->when($result = $string->getByteAt(2))
695             ->then
696                 ->integer(ord($result))
697                     ->isEqualTo(0x92)
698 
699             ->when($result = $string->getByteAt(3))
700             ->then
701                 ->integer(ord($result))
702                     ->isEqualTo(0xa9)
703 
704             ->when($result = $string->getByteAt(-1))
705             ->then
706                 ->integer(ord($result))
707                     ->isEqualTo(0xa9);
708     }
709 
710     public function case_bytes_length()
711     {
712         $this
713             ->given($string = new LUT('��'))
714             ->when($result = $string->getBytesLength())
715             ->then
716                 ->integer($result)
717                     ->isEqualTo(4);
718     }
719 
720     public function case_get_width()
721     {
722         $this
723             ->given($string = new LUT('��'))
724             ->when($result = $string->getWidth())
725             ->then
726                 ->integer($result)
727                     ->isEqualTo(1)
728 
729             ->given($string = new LUT('習'))
730             ->when($result = $string->getWidth())
731             ->then
732                 ->integer($result)
733                     ->isEqualTo(2);
734     }
735 
736     public function case_get_char_direction()
737     {
738         $this
739             ->when($result = LUT::getCharDirection('A'))
740             ->then
741                 ->integer($result)
742                     ->isEqualTo(LUT::LTR)
743 
744             ->when($result = LUT::getCharDirection('ا'))
745             ->then
746                 ->integer($result)
747                     ->isEqualTo(LUT::RTL);
748     }
749 
750     public function case_get_char_width()
751     {
752         $this
753             ->given(
754                 $data = [
755                     // 8-bit control character.
756                     [0x0,    0],
757                     [0x19,  -1],
758                     [0x7f,  -1],
759                     [0x9f,  -1],
760 
761                     // Regular.
762                     [0xa0,   1],
763 
764                     // Non-spacing characters mark.
765                     [0x300,  0], // in Mn
766                     [0x488,  0], // in Me
767                     [0x600,  0], // in Cf
768                     [0xad,   1], // in Cf, but the only exception
769                     [0x1160, 0],
770                     [0x11ff, 0],
771                     [0x200b, 0],
772 
773                     // To test the last return statement.
774                     [0x1100, 2],
775                     [0x2160, 1],
776                     [0x3f60, 2],
777                     [0x303f, 1],
778                     [0x2329, 2],
779                     [0xaed0, 2],
780                     [0x232a, 2],
781                     [0xffa4, 1],
782                     [0xfe10, 2],
783                     [0xfe30, 2],
784                     [0xff00, 2],
785                     [0xf900, 2]
786                 ]
787             )
788             ->when(function () use ($data) {
789                 foreach ($data as $datum) {
790                     list($code, $width) = $datum;
791 
792                     $this
793                         ->when($result = LUT::getCharWidth(LUT::fromCode($code)))
794                         ->then
795                             ->integer($result)
796                                 ->isEqualTo($width);
797                 }
798             });
799     }
800 
801     public function case_is_char_printable()
802     {
803         $this
804             ->when($result = LUT::isCharPrintable(LUT::fromCode(0x7f)))
805             ->then
806                 ->boolean($result)
807                     ->isFalse()
808 
809             ->when($result = LUT::isCharPrintable(LUT::fromCode(0xa0)))
810             ->then
811                 ->boolean($result)
812                     ->isTrue()
813 
814             ->when($result = LUT::isCharPrintable(LUT::fromCode(0x1100)))
815             ->then
816                 ->boolean($result)
817                     ->isTrue();
818     }
819 
820     public function case_from_code()
821     {
822         $this
823             // U+0000 to U+007F
824             ->when($result = LUT::fromCode(0x7e))
825             ->then
826                 ->string($result)
827                     ->isEqualTo('~')
828 
829             // U+0080 to U+07FF
830             ->when($result = LUT::fromCode(0xa7))
831             ->then
832                 ->string($result)
833                     ->isEqualTo('§')
834 
835             // U+0800 to U+FFFF
836             ->when($result = LUT::fromCode(0x1207))
837             ->then
838                 ->string($result)
839                     ->isEqualTo('ሇ')
840 
841             // U+10000 to U+10FFFF
842             ->when($result = LUT::fromCode(0x1f4a9))
843             ->then
844                 ->string($result)
845                     ->isEqualTo('��');
846     }
847 
848     public function case_to_code()
849     {
850         $this
851             // U+0000 to U+007F
852             ->when($result = LUT::toCode('~'))
853             ->then
854                 ->integer($result)
855                     ->isEqualTo(0x7e)
856 
857             // U+0080 to U+07FF
858             ->when($result = LUT::toCode('§'))
859             ->then
860                 ->integer($result)
861                     ->isEqualTo(0xa7)
862 
863             // U+0800 to U+FFFF
864             ->when($result = LUT::toCode('ሇ'))
865             ->then
866                 ->integer($result)
867                     ->isEqualTo(0x1207)
868 
869             // U+10000 to U+10FFFF
870             ->when($result = LUT::toCode('��'))
871             ->then
872                 ->integer($result)
873                     ->isEqualTo(0x1f4a9);
874     }
875 
876     public function case_to_binary_code()
877     {
878         $this
879             // U+0000 to U+007F
880             ->when($result = LUT::toBinaryCode('~'))
881             ->then
882                 ->string($result)
883                     ->isEqualTo('01111110')
884 
885             // U+0080 to U+07FF
886             ->when($result = LUT::toBinaryCode('§'))
887             ->then
888                 ->string($result)
889                     ->isEqualTo('1100001010100111')
890 
891             // U+0800 to U+FFFF
892             ->when($result = LUT::toBinaryCode('ሇ'))
893             ->then
894                 ->string($result)
895                     ->isEqualTo('111000011000100010000111')
896 
897             // U+10000 to U+10FFFF
898             ->when($result = LUT::toBinaryCode('��'))
899             ->then
900                 ->string($result)
901                     ->isEqualTo('11110000100111111001001010101001');
902     }
903 
904     public function case_transcode_no_iconv()
905     {
906         $this
907             ->given(
908                 $this->function->function_exists = function ($name) {
909                     return 'iconv' !== $name;
910                 }
911             )
912             ->exception(function () {
913                 LUT::transcode('foo', 'UTF-8');
914             })
915                 ->isInstanceOf('Hoa\Ustring\Exception');
916     }
917 
918     public function case_transcode_and_isUtf8()
919     {
920         $this
921             ->given($ = 'Σ')
922             ->when($Σ = LUT::transcode($, 'UTF-8', 'UTF-16'))
923             ->then
924                 ->string($Σ)
925                     ->isNotEqualTo($)
926                 ->boolean(LUT::isUtf8($Σ))
927                     ->isFalse()
928 
929             ->when($Σ = LUT::transcode($Σ, 'UTF-16', 'UTF-8'))
930                 ->string($Σ)
931                     ->isEqualTo($)
932                 ->boolean(LUT::isUtf8($Σ))
933                     ->isTrue()
934                 ->boolean(LUT::isUtf8($))
935                     ->isTrue();
936     }
937 
938     public function case_to_ascii_no_transliterator_no_normalizer()
939     {
940         $this
941             ->given(
942                 $this->function->class_exists = function ($name) {
943                     return false === in_array($name, ['Transliterator', 'Normalizer']);
944                 },
945                 $string = new LUT('Un été brûlant sur la côte')
946             )
947             ->exception(function () use ($string) {
948                 $string->toAscii();
949             })
950                 ->isInstanceOf('Hoa\Ustring\Exception');
951     }
952 
953     public function case_to_ascii_no_transliterator_no_normalizer_try()
954     {
955         $this
956             ->given(
957                 $this->function->class_exists = function ($name) {
958                     return false === in_array($name, ['Transliterator', 'Normalizer']);
959                 },
960                 $string = new LUT('Un été brûlant sur la côte')
961             )
962             ->when($result = $string->toAscii(true))
963             ->then
964                 ->object($result)
965                     ->isIdenticalTo($string)
966                 ->string((string) $result)
967                     ->isEqualTo('Un ete brulant sur la cote');
968     }
969 
970     public function case_to_ascii_no_transliterator()
971     {
972         $this
973             ->given(
974                 $this->function->class_exists = function ($name) {
975                     return 'Transliterator' !== $name;
976                 },
977                 $string = new LUT('Un été brûlant sur la côte')
978             )
979             ->when($result = $string->toAscii())
980             ->then
981                 ->object($result)
982                     ->isIdenticalTo($string)
983                 ->string((string) $result)
984                     ->isEqualTo('Un ete brulant sur la cote');
985     }
986 
987     public function case_to_ascii()
988     {
989         $this
990             ->given(
991                 $strings = [
992                     'Un été brûlant sur la côte'
993                     => 'Un ete brulant sur la cote',
994 
995                     'Αυτή είναι μια δοκιμή'
996                     => 'Aute einai mia dokime',
997 
998                     'أحبك'
999                     => 'ahbk',
1000 
1001                     'キャンパス'
1002                     => 'kyanpasu',
1003 
1004                     'биологическом'
1005                     => 'biologiceskom',
1006 
1007                     '정, 병호'
1008                     => 'jeong, byeongho',
1009 
1010                     'ますだ, よしひこ'
1011                     => 'masuda, yoshihiko',
1012 
1013                     'मोनिच'
1014                     => 'monica',
1015 
1016                     'क्ष'
1017                     => 'ksa',
1018 
1019                     'أحبك ��'
1020                     => 'ahbk (grinning face)',
1021 
1022                     '∀ i ∈ ℕ'
1023                     => '(for all) i (element of) N'
1024                 ]
1025             )
1026             ->when(function () use ($strings) {
1027                 foreach ($strings as $original => $asciied) {
1028                     $this
1029                         ->given($string = new LUT($original))
1030                         ->when($result = $string->toAscii())
1031                         ->then
1032                             ->object($result)
1033                                 ->isIdenticalTo($string)
1034                             ->string((string) $result)
1035                                 ->isEqualTo($asciied);
1036                 }
1037             });
1038     }
1039 
1040     public function case_copy()
1041     {
1042         $this
1043             ->given($string = new LUT('foo'))
1044             ->when($result = $string->copy())
1045             ->then
1046                 ->object($result)
1047                     ->isEqualTo($string);
1048     }
1049 
1050     public function case_toString()
1051     {
1052         $this
1053             ->given($datum = $this->sample($this->realdom->regex('/\w{7,42}/')))
1054             ->when($result = new LUT($datum))
1055             ->then
1056                 ->castToString($result)
1057                     ->isEqualTo($datum);
1058     }
1059 }
1060