Skip to content

Commit 5e27f88

Browse files
committed
Moar tests
1 parent 94b633a commit 5e27f88

File tree

3 files changed

+74
-17
lines changed

3 files changed

+74
-17
lines changed

src/main/java/graphql/validation/directives/AbstractDirectiveValidationRule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ protected BigDecimal asBigDecimal(Object value) throws NumberFormatException {
147147
if (value == null) {
148148
return Assert.assertShouldNeverHappen("Validation cant handle null objects BigDecimals");
149149
}
150+
if (value instanceof BigDecimal) {
151+
return (BigDecimal) value;
152+
}
150153
String bdStr = "";
151154
if (value instanceof Number) {
152155
bdStr = value.toString();

src/main/java/graphql/validation/directives/standardrules/DigitsRule.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package graphql.validation.directives.standardrules;
22

3-
import graphql.Assert;
43
import graphql.GraphQLError;
54
import graphql.Scalars;
65
import graphql.schema.GraphQLDirective;
@@ -28,6 +27,7 @@ public String getDirectiveDeclarationSDL() {
2827
@Override
2928
public boolean appliesToType(GraphQLInputType inputType) {
3029
return isOneOfTheseTypes(inputType,
30+
Scalars.GraphQLString,
3131
Scalars.GraphQLByte,
3232
Scalars.GraphQLShort,
3333
Scalars.GraphQLInt,
@@ -42,33 +42,35 @@ public boolean appliesToType(GraphQLInputType inputType) {
4242
@Override
4343
public List<GraphQLError> runValidation(ValidationRuleEnvironment ruleEnvironment) {
4444
Object argumentValue = ruleEnvironment.getFieldOrArgumentValue();
45+
if (argumentValue == null) {
46+
return Collections.emptyList();
47+
}
4548

4649
GraphQLDirective directive = ruleEnvironment.getContextObject(GraphQLDirective.class);
4750
int maxIntegerLength = getIntArg(directive, "integer");
4851
int maxFractionLength = getIntArg(directive, "fraction");
4952

50-
if (argumentValue == null) {
51-
return Collections.emptyList();
52-
}
53-
54-
BigDecimal bigNum;
55-
if (argumentValue instanceof BigDecimal) {
56-
bigNum = (BigDecimal) argumentValue;
57-
} else if (argumentValue instanceof Number) {
58-
bigNum = new BigDecimal(argumentValue.toString()).stripTrailingZeros();
59-
} else {
60-
return Assert.assertShouldNeverHappen("You MUST provide a Number of the Digits directive rule");
53+
boolean isOk;
54+
try {
55+
BigDecimal bigNum = asBigDecimal(argumentValue);
56+
isOk = isOk(bigNum, maxIntegerLength, maxFractionLength);
57+
} catch (NumberFormatException e) {
58+
isOk = false;
6159
}
6260

63-
int integerPartLength = bigNum.precision() - bigNum.scale();
64-
int fractionPartLength = bigNum.scale() < 0 ? 0 : bigNum.scale();
65-
66-
if (!(maxIntegerLength >= integerPartLength && maxFractionLength >= fractionPartLength)) {
61+
if (!isOk) {
6762
return mkError(ruleEnvironment, directive, mkMessageParams(
6863
"integer", maxIntegerLength,
69-
"fraction", fractionPartLength,
64+
"fraction", maxFractionLength,
7065
"fieldOrArgumentValue", argumentValue));
7166
}
7267
return Collections.emptyList();
7368
}
69+
70+
private boolean isOk(BigDecimal bigNum, int maxIntegerLength, int maxFractionLength) {
71+
int integerPartLength = bigNum.precision() - bigNum.scale();
72+
int fractionPartLength = bigNum.scale() < 0 ? 0 : bigNum.scale();
73+
74+
return maxIntegerLength >= integerPartLength && maxFractionLength >= fractionPartLength;
75+
}
7476
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package graphql.validation.directives.standardrules
2+
3+
4+
import graphql.validation.directives.BaseDirectiveRuleTest
5+
import graphql.validation.directives.DirectiveValidationRule
6+
import spock.lang.Unroll
7+
8+
class DigitsRuleTest extends BaseDirectiveRuleTest {
9+
10+
11+
@Unroll
12+
def "digit rule constraints"() {
13+
14+
DirectiveValidationRule ruleUnderTest = new DigitsRule()
15+
16+
expect:
17+
18+
def errors = runRules(ruleUnderTest, fieldDeclaration, "arg", argVal)
19+
assertErrors(errors, expectedMessage)
20+
21+
where:
22+
23+
fieldDeclaration | argVal | expectedMessage
24+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | null | ''
25+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | Byte.valueOf("0") | ''
26+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | Double.valueOf("500.2") | ''
27+
28+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | new BigDecimal("-12345.12") | ''
29+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | new BigDecimal("-123456.12") | 'Digits;path=/arg;val:-123456.12;\t'
30+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | new BigDecimal("-123456.123") | 'Digits;path=/arg;val:-123456.123;\t'
31+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | new BigDecimal("-12345.123") | 'Digits;path=/arg;val:-12345.123;\t'
32+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | new BigDecimal("12345.123") | 'Digits;path=/arg;val:12345.123;\t'
33+
34+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | Float.valueOf("-000000000.22") | ''
35+
36+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | Integer.valueOf("256874") | 'Digits;path=/arg;val:256874;\t'
37+
'field( arg : String @Digits(integer : 5, fraction : 2) ) : ID' | Double.valueOf("12.0001") | 'Digits;path=/arg;val:12.0001;\t'
38+
39+
// zero length
40+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | null | ''
41+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | Byte.valueOf("0") | 'Digits;path=/arg;val:0;\t'
42+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | Double.valueOf("0") | 'Digits;path=/arg;val:0.0;\t'
43+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | new BigDecimal(0) | 'Digits;path=/arg;val:0;\t'
44+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | 0 | 'Digits;path=/arg;val:0;\t'
45+
'field( arg : String @Digits(integer : 0, fraction : 0) ) : ID' | 0L | 'Digits;path=/arg;val:0;\t'
46+
47+
// zeroes are trimmed
48+
'field( arg : String @Digits(integer : 12, fraction : 3) ) : ID' | 0.001d | ''
49+
'field( arg : String @Digits(integer : 12, fraction : 3) ) : ID' | 0.00100d | ''
50+
'field( arg : String @Digits(integer : 12, fraction : 3) ) : ID' | 0.0001d | 'Digits;path=/arg;val:1.0E-4;\t'
51+
}
52+
}

0 commit comments

Comments
 (0)