Skip to content

Commit 3b5ba5a

Browse files
committed
feat: Add defaultValue to apply default values before constraints are checked
1 parent 7a94b1b commit 3b5ba5a

File tree

3 files changed

+89
-5
lines changed

3 files changed

+89
-5
lines changed

models/GenericObject.cfc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,34 @@ component {
3030
* @missingMethodName
3131
* @missingMethodArguments
3232
*/
33-
any function onMissingMethod( required string missingMethodName, required struct missingMethodArguments ){
34-
var key = replaceNoCase( arguments.missingMethodName, "get", "" );
35-
36-
if ( structKeyExists( variables.collection, key ) ) {
33+
any function onMissingMethod( required string missingMethodName, required any missingMethodArguments ){
34+
if ( startsWith( arguments.missingMethodName, "set" ) ) {
35+
var key = mid(
36+
arguments.missingMethodName,
37+
4,
38+
len( arguments.missingMethodName ) - 3
39+
);
40+
variables.collection[ key ] = arguments.missingMethodArguments[ 1 ];
3741
return variables.collection[ key ];
3842
}
3943

44+
if ( startsWith( arguments.missingMethodName, "get" ) ) {
45+
var key = mid(
46+
arguments.missingMethodName,
47+
4,
48+
len( arguments.missingMethodName ) - 3
49+
);
50+
if ( structKeyExists( variables.collection, key ) ) {
51+
return variables.collection[ key ];
52+
}
53+
}
54+
4055
// Return null
56+
return javacast( "null", "" );
57+
}
58+
59+
private boolean function startsWith( word, substring ){
60+
return left( word, len( substring ) ) == substring;
4161
}
4262

4363
}

models/ValidationManager.cfc

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,27 @@ component accessors="true" serialize="false" singleton {
212212
arguments.includeFields = arrayToList( arguments.includeFields );
213213
}
214214

215+
// iterate over fields to apply default values
216+
for ( var thisField in allConstraints ) {
217+
/*
218+
results = results,
219+
rules = allConstraints[ thisField ],
220+
target = arguments.target,
221+
field = thisField,
222+
locale = arguments.locale
223+
*/
224+
if ( allConstraints[ thisField ].keyExists( "defaultValue" ) ) {
225+
var targetValue = invoke( arguments.target, "get" & thisField );
226+
if ( isNull( targetValue ) || !hasValue( targetValue ) ) {
227+
invoke(
228+
arguments.target,
229+
"set" & thisField,
230+
[ allConstraints[ thisField ].defaultValue ]
231+
);
232+
}
233+
}
234+
}
235+
215236
// iterate over constraints defined
216237
for ( var thisField in allConstraints ) {
217238
var validateField = true;
@@ -304,7 +325,7 @@ component accessors="true" serialize="false" singleton {
304325
// process the incoming rules
305326
for ( var key in arguments.rules ) {
306327
// if message validators, just ignore
307-
if ( reFindNoCase( "Message$", key ) ) {
328+
if ( reFindNoCase( "Message$", key ) || key == "defaultValue" ) {
308329
continue;
309330
}
310331

@@ -507,4 +528,36 @@ component accessors="true" serialize="false" singleton {
507528
);
508529
}
509530

531+
/**
532+
* Verify if the target value has a value
533+
* Checks for nullness or for length if it's a simple value, array, query, struct or object.
534+
*/
535+
boolean function hasValue( any targetValue ){
536+
// Null Tests
537+
if ( isNull( arguments.targetValue ) ) {
538+
return false;
539+
}
540+
// Simple Tests
541+
if ( isSimpleValue( arguments.targetValue ) AND len( trim( arguments.targetValue ) ) ) {
542+
return true;
543+
}
544+
// Array Tests
545+
if ( isArray( arguments.targetValue ) and arrayLen( arguments.targetValue ) ) {
546+
return true;
547+
}
548+
// Query Tests
549+
if ( isQuery( arguments.targetValue ) and arguments.targetValue.recordcount ) {
550+
return true;
551+
}
552+
// Struct Tests
553+
if ( isStruct( arguments.targetValue ) and structCount( arguments.targetValue ) ) {
554+
return true;
555+
}
556+
// Object
557+
if ( isObject( arguments.targetValue ) ) {
558+
return true;
559+
}
560+
return false;
561+
}
562+
510563
}

test-harness/tests/specs/ValidationManagerTest.cfc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" {
106106
debug( r.getAllErrors() );
107107
} );
108108

109+
it( "can apply default values before validating", function(){
110+
var mockData = { name : "luis" };
111+
var mockConstraints = {
112+
name : { required : true },
113+
age : { required : true, max : 35, defaultValue : 30 }
114+
};
115+
116+
var r = manager.validate( target = mockData, constraints = mockConstraints );
117+
assertEquals( false, r.hasErrors() );
118+
} );
119+
109120
it( "can validate with specific fields", function(){
110121
var mockData = { name : "", age : "" };
111122
var mockConstraints = {

0 commit comments

Comments
 (0)