Skip to content

Commit 6ca78ba

Browse files
committed
Refactor between rule implementation
1 parent 0952428 commit 6ca78ba

File tree

4 files changed

+55
-166
lines changed

4 files changed

+55
-166
lines changed

src/Translators/Rules.php

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,16 @@ public static function fromColumn(string $context, Column $column)
4949
array_push($rules, 'json');
5050
}
5151

52-
if (in_array($column->dataType(), [
53-
'decimal',
54-
'double',
55-
'float',
56-
'unsignedDecimal',
57-
])) {
52+
if (in_array($column->dataType(), ['decimal', 'double', 'float', 'unsignedDecimal'])) {
5853
array_push($rules, 'numeric');
5954

60-
if (Str::startsWith($column->dataType(), 'unsigned')) {
55+
if (Str::startsWith($column->dataType(), 'unsigned') || in_array('unsigned', $column->modifiers())) {
6156
array_push($rules, 'gt:0');
6257
}
58+
59+
if (!empty($column->attributes())) {
60+
array_push($rules, self::betweenRuleForColumn($column));
61+
}
6362
}
6463

6564
if (in_array($column->dataType(), ['enum', 'set'])) {
@@ -80,18 +79,6 @@ public static function fromColumn(string $context, Column $column)
8079
array_push($rules, 'unique:' . $context . ',' . $column->name());
8180
}
8281

83-
if (Str::contains($column->dataType(), 'decimal')) {
84-
array_push($rules, self::betweenRuleForNumericTypes($column, 'decimal'));
85-
}
86-
87-
if (Str::contains($column->dataType(), 'float')) {
88-
array_push($rules, self::betweenRuleForNumericTypes($column, 'float'));
89-
}
90-
91-
if (Str::contains($column->dataType(), 'double')) {
92-
array_push($rules, self::betweenRuleForNumericTypes($column, 'double'));
93-
}
94-
9582
return $rules;
9683
}
9784

@@ -108,30 +95,23 @@ private static function overrideStringRuleForSpecialNames($name)
10895
}
10996

11097

111-
private static function betweenRuleForNumericTypes(Column $column, $numericType)
98+
private static function betweenRuleForColumn(Column $column)
11299
{
113-
$parameters = explode(",", Str::between($column->dataType(), "$numericType:", " "));
114-
115-
if (count($parameters) === 1) {
116-
return;
117-
}
118-
119-
[$precision, $scale] = $parameters;
100+
$precision = $column->attributes()[0];
101+
$scale = $column->attributes()[1] ?? 0;
120102

121-
$max = substr_replace(str_pad("", $precision, '9'), ".", $precision - $scale, 0);
122-
$min = "-" . $max;
103+
$value = substr_replace(str_pad("", $precision, '9'), ".", $precision - $scale, 0);
123104

124105
if (intval($scale) === 0) {
125-
$min = trim($min, ".");
126-
$max = trim($max, ".");
106+
$value = trim($value, ".");
127107
}
128108

129-
if (Str::contains($column->dataType(), 'unsigned')) {
130-
$min = '0';
109+
if ($precision == $scale) {
110+
$value = '0' . $value;
131111
}
132112

133-
$betweenRule = 'between:' . $min . ',' . $max;
113+
$min = $column->dataType() === 'unsignedDecimal' || in_array('unsigned', $column->modifiers()) ? '0' : '-' . $value;
134114

135-
return $betweenRule;
115+
return 'between:' . $min . ',' . $value;
136116
}
137117
}

tests/Feature/Translators/RulesTest.php

Lines changed: 35 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -194,128 +194,30 @@ public function forColumn_does_not_return_between_rule_for_unsigned_decimal_with
194194

195195
/**
196196
* @test
197-
* @dataProvider numericDataProvider
197+
* @dataProvider noBetweenRuleDataProvider
198198
*/
199-
public function forColumn_return_between_rule_for_decimal($precision, $scale, $interval)
199+
public function forColumn_does_not_return_between_rule_for_double_without_precion_and_scale($column)
200200
{
201-
$column = new Column('column', "decimal:$precision,$scale");
202-
203-
$this->assertContains("between:$interval", Rules::fromColumn('context', $column));
204-
}
205-
206-
/**
207-
* @test
208-
* @dataProvider unsignedNumericDataProvider
209-
*/
210-
public function forColumn_return_between_rule_for_unsigned_decimal($precision, $scale, $interval)
211-
{
212-
$unsignedBeforeDecimalColumn = new Column('column', "unsigned decimal:$precision,$scale");
213-
214-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedBeforeDecimalColumn));
215-
216-
$unsignedAfterDecimalColumn = new Column('column', "decimal:$precision,$scale unsigned");
217-
218-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedAfterDecimalColumn));
219-
}
220-
221-
/**
222-
* @test
223-
*/
224-
public function forColumn_does_not_return_between_rule_for_float_without_precion_and_scale()
225-
{
226-
$column = new Column('column', "float");
227-
228201
$this->assertNotContains("between", Rules::fromColumn('context', $column));
229202
}
230203

231204
/**
232-
* @test
233-
*/
234-
public function forColumn_does_not_return_between_rule_for_unsigned_float_without_precion_and_scale()
235-
{
236-
$unsignedBeforeFloatColumn = new Column('column', "unsigned float");
237-
238-
$this->assertNotContains("between", Rules::fromColumn('context', $unsignedBeforeFloatColumn));
239-
240-
$unsignedAfterFloatColumn = new Column('column', "float unsigned");
241-
242-
$this->assertNotContains("between", Rules::fromColumn('context', $unsignedAfterFloatColumn));
243-
}
244-
245-
/**
246-
* @test
247-
* @dataProvider numericDataProvider
248-
*/
249-
public function forColumn_return_between_rule_for_float($precision, $scale, $interval)
250-
{
251-
$column = new Column('column', "float:$precision,$scale");
252-
253-
$this->assertContains("between:$interval", Rules::fromColumn('context', $column));
254-
}
255-
256-
/**
257-
* @test
258-
* @dataProvider unsignedNumericDataProvider
259-
*/
260-
public function forColumn_return_between_rule_for_unsigned_float($precision, $scale, $interval)
261-
{
262-
$unsignedBeforeFloatColumn = new Column('column', "unsigned float:$precision,$scale");
263-
264-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedBeforeFloatColumn));
265-
266-
$unsignedAfterFloatColumn = new Column('column', "float:$precision,$scale unsigned");
267-
268-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedAfterFloatColumn));
269-
}
270-
271-
/**
272-
* @test
273-
*/
274-
public function forColumn_does_not_return_between_rule_for_double_without_precion_and_scale()
205+
* @test
206+
* @dataProvider noBetweenRuleDataProvider
207+
*/
208+
public function forColumn_does_not_return_between_rule($column)
275209
{
276-
$column = new Column('column', "double");
277-
278210
$this->assertNotContains("between", Rules::fromColumn('context', $column));
279211
}
280212

281213
/**
282214
* @test
215+
* @dataProvider betweenRuleDataProvider
283216
*/
284-
public function forColumn_does_not_return_between_rule_for_unsigned_double_without_precion_and_scale()
217+
public function forColumn_returns_between_rule($column, $interval)
285218
{
286-
$unsignedBeforeDoubleColumn = new Column('column', "unsigned double");
287-
288-
$this->assertNotContains("between", Rules::fromColumn('context', $unsignedBeforeDoubleColumn));
289-
290-
$unsignedAfterDoubleColumn = new Column('column', "double unsigned");
291-
292-
$this->assertNotContains("between", Rules::fromColumn('context', $unsignedAfterDoubleColumn));
293-
}
294-
295-
/**
296-
* @test
297-
* @dataProvider numericDataProvider
298-
*/
299-
public function forColumn_return_between_rule_for_double($precision, $scale, $interval)
300-
{
301-
$column = new Column('column', "double:$precision,$scale");
302-
303-
$this->assertContains("between:$interval", Rules::fromColumn('context', $column));
304-
}
305-
306-
/**
307-
* @test
308-
* @dataProvider unsignedNumericDataProvider
309-
*/
310-
public function forColumn_return_between_rule_for_unsigned_double($precision, $scale, $interval)
311-
{
312-
$unsignedBeforeDoubleColumn = new Column('column', "unsigned double:$precision,$scale");
313-
314-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedBeforeDoubleColumn));
315-
316-
$unsignedAfterDoubleColumn = new Column('column', "double:$precision,$scale unsigned");
317-
318-
$this->assertContains("between:$interval", Rules::fromColumn('context', $unsignedAfterDoubleColumn));
219+
$fromColumn = Rules::fromColumn('context', $column);
220+
$this->assertContains("between:$interval", $fromColumn);
319221
}
320222

321223
public function stringDataTypesProvider()
@@ -376,35 +278,38 @@ public function relationshipColumnProvider()
376278
];
377279
}
378280

379-
public function numericDataProvider()
281+
public function noBetweenRuleDataProvider()
380282
{
381283
return [
382-
['10', '0', '-9999999999,9999999999'],
383-
['10', '1', '-999999999.9,999999999.9'],
384-
['10', '2', '-99999999.99,99999999.99'],
385-
['10', '3', '-9999999.999,9999999.999'],
386-
['10', '4', '-999999.9999,999999.9999'],
387-
['10', '5', '-99999.99999,99999.99999'],
388-
['10', '6', '-9999.999999,9999.999999'],
389-
['10', '7', '-999.9999999,999.9999999'],
390-
['10', '8', '-99.99999999,99.99999999'],
391-
['10', '9', '-9.999999999,9.999999999'],
284+
[new Column('column', 'float')],
285+
[new Column('column', 'double')],
286+
[new Column('column', 'decimal')],
287+
[new Column('column', 'unsignedDecimal')],
288+
[new Column('column', 'float', ['unsigned'])],
289+
[new Column('column', 'double', ['unsigned'])],
290+
[new Column('column', 'decimal', ['unsigned'])],
392291
];
393292
}
394293

395-
public function unsignedNumericDataProvider()
294+
public function betweenRuleDataProvider()
396295
{
397296
return [
398-
['10', '0', '0,9999999999'],
399-
['10', '1', '0,999999999.9'],
400-
['10', '2', '0,99999999.99'],
401-
['10', '3', '0,9999999.999'],
402-
['10', '4', '0,999999.9999'],
403-
['10', '5', '0,99999.99999'],
404-
['10', '6', '0,9999.999999'],
405-
['10', '7', '0,999.9999999'],
406-
['10', '8', '0,99.99999999'],
407-
['10', '9', '0,9.999999999'],
297+
[new Column('column', 'double', [], [8, 0]), '-99999999,99999999'],
298+
[new Column('column', 'double', [], [10, 1]), '-999999999.9,999999999.9'],
299+
[new Column('column', 'double', [], [10, 2]), '-99999999.99,99999999.99'],
300+
[new Column('column', 'decimal', [], [10, 3]), '-9999999.999,9999999.999'],
301+
[new Column('column', 'decimal', [], [10, 4]), '-999999.9999,999999.9999'],
302+
[new Column('column', 'decimal', [], [10, 5]), '-99999.99999,99999.99999'],
303+
[new Column('column', 'float', [], [10, 6]), '-9999.999999,9999.999999'],
304+
[new Column('column', 'float', [], [10, 7]), '-999.9999999,999.9999999'],
305+
[new Column('column', 'float', [], [10, 8]), '-99.99999999,99.99999999'],
306+
[new Column('column', 'double', [], [4, 4]), '-0.9999,0.9999'],
307+
[new Column('column', 'unsignedDecimal', [], [10, 0]), '0,9999999999'],
308+
[new Column('column', 'unsignedDecimal', [], [8, 1]), '0,9999999.9'],
309+
[new Column('column', 'unsignedDecimal', [], [6, 2]), '0,9999.99'],
310+
[new Column('column', 'decimal', ['unsigned'], [10, 3]), '0,9999999.999'],
311+
[new Column('column', 'double', ['unsigned'], [10, 4]), '0,999999.9999'],
312+
[new Column('column', 'float', ['unsigned'], [10, 5]), '0,99999.99999'],
408313
];
409314
}
410315
}

tests/fixtures/definitions/validate-statements.bp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ models:
22
Post:
33
title: string:400
44
content: longtext
5+
rating: decimal:4,2
6+
count: decimal:8 unsigned
57
published_at: nullable timestamp
68

79
controllers:
@@ -11,7 +13,7 @@ controllers:
1113
render: post.index with:posts
1214

1315
store:
14-
validate: title, content
16+
validate: title, content, rating, count
1517
redirect: post.index
1618

1719
Other:

tests/fixtures/form-requests/post-store.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public function rules()
2626
return [
2727
'title' => 'required|string|max:400',
2828
'content' => 'required|string',
29+
'rating' => 'required|numeric|between:-99.99,99.99',
30+
'count' => 'required|numeric|gt:0|between:0,99999999',
2931
];
3032
}
3133
}

0 commit comments

Comments
 (0)