Completed
Push — master ( 17ecb7...725fdf )
by Alexander
15:14
created

NumberTest.php$1 ➔ __toString()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
cc 1
rs 10
1
<?php
2
3
namespace Yiisoft\Validator\Tests\Rule;
4
5
use PHPUnit\Framework\TestCase;
6
use Yiisoft\Validator\DataSetInterface;
7
use Yiisoft\Validator\Rule\Number;
8
9
/**
10
 * @group validators
11
 */
12
class NumberTest extends TestCase
13
{
14
    private $commaDecimalLocales = ['fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252'];
15
    private $pointDecimalLocales = ['en_US.UTF-8', 'en_US.UTF8', 'en_US.utf-8', 'en_US.utf8', 'English_United States.1252'];
16
    private $oldLocale;
17
18
    private function setCommaDecimalLocale(): void
19
    {
20
        if ($this->oldLocale === false) {
21
            $this->markTestSkipped('Your platform does not support locales.');
22
        }
23
24
        if (setlocale(LC_NUMERIC, $this->commaDecimalLocales) === false) {
25
            $this->markTestSkipped('Could not set any of required locales: ' . implode(', ', $this->commaDecimalLocales));
26
        }
27
    }
28
29
    private function setPointDecimalLocale()
30
    {
31
        if ($this->oldLocale === false) {
32
            $this->markTestSkipped('Your platform does not support locales.');
33
        }
34
35
        if (setlocale(LC_NUMERIC, $this->pointDecimalLocales) === false) {
36
            $this->markTestSkipped('Could not set any of required locales: ' . implode(', ', $this->pointDecimalLocales));
37
        }
38
    }
39
40
    private function restoreLocale()
41
    {
42
        setlocale(LC_NUMERIC, $this->oldLocale);
43
    }
44
45
    protected function setUp()
46
    {
47
        parent::setUp();
48
49
        $this->oldLocale = setlocale(LC_NUMERIC, 0);
50
    }
51
52
    public function testvalidateSimple(): void
53
    {
54
        $rule = new Number();
55
        $this->assertTrue($rule->validate(20)->isValid());
56
        $this->assertTrue($rule->validate(0)->isValid());
57
        $this->assertTrue($rule->validate(-20)->isValid());
58
        $this->assertTrue($rule->validate('20')->isValid());
59
        $this->assertTrue($rule->validate(25.45)->isValid());
60
61
        $this->setPointDecimalLocale();
62
        $this->assertFalse($rule->validate('25,45')->isValid());
63
        $this->setCommaDecimalLocale();
64
        $this->assertTrue($rule->validate('25,45')->isValid());
65
        $this->restoreLocale();
66
67
        $this->assertFalse($rule->validate('12:45')->isValid());
68
    }
69
70
    public function testvalidateSimpleInteger()
71
    {
72
        $rule = (new Number())
73
            ->integer();
74
75
        $this->assertTrue($rule->validate(20)->isValid());
76
        $this->assertTrue($rule->validate(0)->isValid());
77
        $this->assertFalse($rule->validate(25.45)->isValid());
78
        $this->assertTrue($rule->validate('20')->isValid());
79
        $this->assertFalse($rule->validate('25,45')->isValid());
80
        $this->assertTrue($rule->validate('020')->isValid());
81
        $this->assertTrue($rule->validate(0x14)->isValid());
82
        $this->assertFalse($rule->validate('0x14')->isValid()); // todo check this
83
    }
84
85
    public function testvalidateAdvanced()
86
    {
87
        $rule = new Number();
88
        $this->assertTrue($rule->validate('-1.23')->isValid()); // signed float
89
        $this->assertTrue($rule->validate('-4.423e-12')->isValid()); // signed float + exponent
90
        $this->assertTrue($rule->validate('12E3')->isValid()); // integer + exponent
91
        $this->assertFalse($rule->validate('e12')->isValid()); // just exponent
92
        $this->assertFalse($rule->validate('-e3')->isValid());
93
        $this->assertFalse($rule->validate('-4.534-e-12')->isValid()); // 'signed' exponent
94
        $this->assertFalse($rule->validate('12.23^4')->isValid()); // expression instead of value
95
    }
96
97
    public function testvalidateAdvancedInteger()
98
    {
99
        $rule = (new Number())->integer();
100
        $this->assertFalse($rule->validate('-1.23')->isValid());
101
        $this->assertFalse($rule->validate('-4.423e-12')->isValid());
102
        $this->assertFalse($rule->validate('12E3')->isValid());
103
        $this->assertFalse($rule->validate('e12')->isValid());
104
        $this->assertFalse($rule->validate('-e3')->isValid());
105
        $this->assertFalse($rule->validate('-4.534-e-12')->isValid());
106
        $this->assertFalse($rule->validate('12.23^4')->isValid());
107
    }
108
109
    public function testvalidateWithLocaleWhereDecimalPointIsComma(): void
110
    {
111
        $rule = new Number();
112
113
        $this->setPointDecimalLocale();
114
        $this->assertTrue($rule->validate(.5)->isValid());
115
116
        $this->setCommaDecimalLocale();
117
        $this->assertTrue($rule->validate(.5)->isValid());
118
119
        $this->restoreLocale();
120
    }
121
122
    public function testvalidateMin()
123
    {
124
        $rule = (new Number())
125
            ->min(1);
126
127
        $this->assertTrue($rule->validate(1)->isValid());
128
129
        $result = $rule->validate(-1);
130
        $this->assertFalse($result->isValid());
131
        $this->assertContains('must be no less than 1.', $result->getErrors()[0]);
132
133
        $this->assertFalse($rule->validate('22e-12')->isValid());
134
        $this->assertTrue($rule->validate(PHP_INT_MAX + 1)->isValid());
135
    }
136
137
    public function testvalidateMinInteger()
138
    {
139
        $rule = (new Number())
140
            ->min(1)
141
            ->integer();
142
143
        $this->assertTrue($rule->validate(1)->isValid());
144
        $this->assertFalse($rule->validate(-1)->isValid());
145
        $this->assertFalse($rule->validate('22e-12')->isValid());
146
        $this->assertTrue($rule->validate(PHP_INT_MAX + 1)->isValid());
147
    }
148
149
    public function testvalidateMax()
150
    {
151
        $rule = (new Number())
152
            ->max(1.25);
153
154
        $this->assertTrue($rule->validate(1)->isValid());
155
        $this->assertFalse($rule->validate(1.5)->isValid());
156
        $this->assertTrue($rule->validate('22e-12')->isValid());
157
        $this->assertTrue($rule->validate('125e-2')->isValid());
158
    }
159
160
    public function testvalidateMaxInteger()
161
    {
162
        $rule = (new Number())
163
            ->max(1.25)
164
            ->integer();
165
166
        $this->assertTrue($rule->validate(1)->isValid());
167
        $this->assertFalse($rule->validate(1.5)->isValid());
168
        $this->assertFalse($rule->validate('22e-12')->isValid());
169
        $this->assertFalse($rule->validate('125e-2')->isValid());
170
    }
171
172
    public function testvalidateRange()
173
    {
174
        $rule = (new Number())
175
            ->min(-10)
176
            ->max(20);
177
178
        $this->assertTrue($rule->validate(0)->isValid());
179
        $this->assertTrue($rule->validate(-10)->isValid());
180
        $this->assertFalse($rule->validate(-11)->isValid());
181
        $this->assertFalse($rule->validate(21)->isValid());
182
    }
183
184
    public function testvalidateRangeInteger()
185
    {
186
        $rule = (new Number())
187
            ->min(-10)
188
            ->max(20)
189
            ->integer();
190
191
        $this->assertTrue($rule->validate(0)->isValid());
192
        $this->assertFalse($rule->validate(-11)->isValid());
193
        $this->assertFalse($rule->validate(22)->isValid());
194
        $this->assertFalse($rule->validate('20e-1')->isValid());
195
    }
196
197
    public function testScientificFormat(): void
198
    {
199
        $rule = new Number();
200
        $result = $rule->validate('5.5e1');
201
        $this->assertTrue($result->isValid());
202
    }
203
204
    public function testExpressionFormat(): void
205
    {
206
        $rule = new Number();
207
        $result = $rule->validate('43^32');
208
        $this->assertFalse($result->isValid());
209
    }
210
211
    public function testMinEdge(): void
212
    {
213
        $rule = (new Number())
214
            ->min(10);
215
216
        $result = $rule->validate(10);
217
        $this->assertTrue($result->isValid());
218
    }
219
220
    public function testLessThanMin(): void
221
    {
222
        $rule = (new Number())
223
            ->min(10);
224
225
        $result = $rule->validate(5);
226
        $this->assertFalse($result->isValid());
227
    }
228
229
    public function testMaxEdge(): void
230
    {
231
        $rule = (new Number())
232
            ->max(10);
233
234
        $result = $rule->validate(10);
235
        $this->assertTrue($result->isValid());
236
    }
237
238
    public function testMaxEdgeInteger(): void
239
    {
240
        $rule = (new Number())
241
            ->max(10)
242
            ->integer();
243
244
        $result = $rule->validate(10);
245
        $this->assertTrue($result->isValid());
246
    }
247
248
    public function testMoreThanMax(): void
249
    {
250
        $rule = (new Number())
251
            ->max(10);
252
253
        $result = $rule->validate(15);
254
        $this->assertFalse($result->isValid());
255
    }
256
257
    public function testFloatWithInteger(): void
258
    {
259
        $rule = (new Number())
260
            ->max(10)
261
            ->integer();
262
263
        $result = $rule->validate(3.43);
264
        $this->assertFalse($result->isValid());
265
    }
266
267
    public function testArray(): void
268
    {
269
        $rule = (new Number())
270
            ->min(1);
271
272
        $result = $rule->validate([1, 2, 3]);
273
        $this->assertFalse($result->isValid());
274
    }
275
276
    /**
277
     * @see https://github.com/yiisoft/yii2/issues/11672
278
     */
279
    public function testStdClass(): void
280
    {
281
        $rule = (new Number())
282
            ->min(1);
283
284
        $result = $rule->validate(new \stdClass());
285
        $this->assertFalse($result->isValid());
286
    }
287
288
    public function getDataSet(array $attributeValues): DataSetInterface
289
    {
290
        return new class ($attributeValues) implements DataSetInterface
291
        {
292
            private $data;
293
294
            public function __construct(array $data)
295
            {
296
                $this->data = $data;
297
            }
298
299
            public function getValue(string $key)
300
            {
301
                if (isset($this->data[$key])) {
302
                    return $this->data[$key];
303
                }
304
305
                throw new \RuntimeException("There is no $key in the class.");
306
            }
307
        };
308
    }
309
310
    public function testEnsureCustomMessageIsSetOnvalidate(): void
311
    {
312
        $rule = (new Number())
313
            ->min(5)
314
            ->tooSmallMessage('Value is too small.');
315
316
        $result = $rule->validate(0);
317
        $this->assertFalse($result->isValid());
318
        $this->assertCount(1, $result->getErrors());
319
        $errors = $result->getErrors();
320
        $this->assertSame('Value is too small.', $errors[0]);
321
    }
322
323
    public function testValidateObject(): void
324
    {
325
        $rule = new Number();
326
        $value = new \stdClass();
327
        $this->assertFalse($rule->validate($value)->isValid());
328
    }
329
330
    public function testValidateResource(): void
331
    {
332
        $rule = new Number();
333
        $fp = fopen('php://stdin', 'r');
334
        $this->assertFalse($rule->validate($fp)->isValid());
335
336
        $result = $rule->validate($fp);
337
        $this->assertFalse($result->isValid());
338
339
        // the check is here for HHVM that
340
        // was losing handler for unknown reason
341
        if (is_resource($fp)) {
342
            fclose($fp);
343
        }
344
    }
345
346
    public function testValidateToString(): void
347
    {
348
        $rule = new Number();
349
        $object = new class('10')
350
        {
351
            public $foo;
352
353
            public function __construct($foo)
354
            {
355
                $this->foo = $foo;
356
            }
357
358
            public function __toString(): string
359
            {
360
                return $this->foo;
361
            }
362
        };
363
        $this->assertTrue($rule->validate($object)->isValid());
364
    }
365
}
366