From 2cb008cccd39c4d13a7a66ed991c382e807bd94e Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Tue, 15 Feb 2022 15:09:18 +0000 Subject: [PATCH 1/5] Started the process of fully wrapping fflib_Criteria Allows for better fluidity in using code and more consistent parameter checking Have wrapped and implemented all inSet and notInSet implementations --- .../classes/criteria/fflib_Criteria.cls | 2 +- .../fflib-extension/ortoo_Criteria.cls | 651 +++++++++++++++++- .../tests/ortoo_CriteriaTest.cls | 620 +++++++++++++++++ 3 files changed, 1256 insertions(+), 17 deletions(-) diff --git a/framework/default/fflib-apex-extensions/default/classes/criteria/fflib_Criteria.cls b/framework/default/fflib-apex-extensions/default/classes/criteria/fflib_Criteria.cls index 153f93a1e44..ff4f1f58b89 100755 --- a/framework/default/fflib-apex-extensions/default/classes/criteria/fflib_Criteria.cls +++ b/framework/default/fflib-apex-extensions/default/classes/criteria/fflib_Criteria.cls @@ -57,7 +57,7 @@ public virtual with sharing class fflib_Criteria /** * Adds the given evalutor onto the formula stack */ - protected void addEvaluator( Evaluator evaluator ) + public void addEvaluator( Evaluator evaluator ) { evaluators.add( evaluator ); } diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls index 57de5cfc164..267a518a099 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls @@ -3,18 +3,295 @@ * * @group fflib Extension */ -public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria implements ISearchCriteria // NOPMD: specified a mini-namespace to differentiate from fflib versions +public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria // NOPMD: specified a mini-namespace to differentiate from fflib versions { + fflib_Criteria criteria; - public virtual ortoo_Criteria likeString( Schema.SObjectField field, Object value ) + public ortoo_Criteria() { - addEvaluator( new FieldEvaluator( field, fflib_Operator.LIKEx, value ) ); + criteria = new fflib_Criteria(); + } + + public String toSOQL() + { + return criteria.toSOQL(); + } + + // TODO: add remaining public methods from fflib_Criteria + // TODO: change SObjects2 to allow ortoo_Criteria - maybe define an interface instead + + /** + * Checks if the given field has a value 'like' that given + * + * @param field The field to check the value of + * @param values The value that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .likeString( Account.Type, 'Customer%' ) + * + * Evaluates: + * Type LIKE 'Customer%' + */ + public ortoo_Criteria likeString( Schema.SObjectField field, String value ) + { + Contract.requires( field != null, 'likeString called with a null field' ); + if ( ! String.isEmpty( value ) ) + { + criteria.addEvaluator( new fflib_Criteria.FieldEvaluator( field, fflib_Operator.LIKEx, value ) ); + } + return this; + } + + /** + * Checks if the given field has a value 'like' that given + * + * @param relatedField The name of the to check the value of + * @param values The value that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .likeString( 'Account.Type', 'Customer%' ) + * + * Evaluates: + * Account.Type LIKE 'Customer%' + */ + public ortoo_Criteria likeString( String relatedField, String value ) + { + Contract.requires( relatedField != null, 'likeString called with a null relatedField' ); + if ( ! String.isEmpty( value ) ) + { + criteria.addEvaluator( new fflib_Criteria.RelatedFieldEvaluator( relatedField, fflib_Operator.LIKEx, value ) ); + } + return this; + } + + /** + * Checks if the given field has a value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Type, new Set{'Customer', 'Competitor', 'Partner'} ) + * + * Evaluates: + * Type IN ('Customer','Competitor','Partner') + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Objects( new List( values ) ) ); + return this; + } + + /** + * Checks if the given field has a DateTime value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.DateTime_Value__c, new Set{ Date.newInstanceGmt( 2020, 01, 02, 11, 20, 00 ), Date.newInstance( 2021, 01, 02, 11, 00, 20 )} ) + * + * Evaluates: + * DateTime_Value__c IN (2021-01-02T11:20:00Z,2021-01-02T11:00:20Z) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_DateTimes( values ) ); + return this; + } + + /** + * Checks if the given field has a Date value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Date_Value__c, new Set{ Date.newInstance( 2020, 01, 02 ), Date.newInstance( 2021, 01, 02 )} ) + * + * Evaluates: + * Date_Value__c IN (2021-01-02,2021-01-02) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Dates( values ) ); + return this; + } + + /** + * Checks if the given field has a Decimal value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Decimal_Value__c, new Set{1.1,2.2,3.3} ) + * + * Evaluates: + * Decimal_Value__c IN (1.1,2.2,3.3) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Decimals( values ) ); + return this; + } + + /** + * Checks if the given field has a Double value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Double_Value__c, new Set{1.1,2.2,3.3} ) + * + * Evaluates: + * Double_Value__c IN (1.1,2.2,3.3) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Doubles( values ) ); return this; } - public virtual ortoo_Criteria likeString( String relatedField, Object value ) + /** + * Checks if the given field has an Id value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Id, new Set{'0010t00001bH9q2AAC', '0010t00001bH9q2AAB'} ) + * + * Evaluates: + * Id IN ('0010t00001bH9q2AAC','0010t00001bH9q2AAB') + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) { - addEvaluator( new RelatedFieldEvaluator( relatedField, fflib_Operator.LIKEx, value ) ); + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Ids( values ) ); + return this; + } + + /** + * Checks if the given field has a Integer value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Integer_Value__c, new Set{1,2,3} ) + * + * Evaluates: + * Integer_Value__c IN (1,2,3) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Integers( values ) ); + return this; + } + + /** + * Checks if the given field has a Long value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.Long_Value__c, new Set{1,2,3} ) + * + * Evaluates: + * Long_Value__c IN (1,2,3) + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Longs( values ) ); + return this; + } + + /** + * Checks if the given field has a String value in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .inSet( Account.String_Value__c, new Set{'one','two'} ) + * + * Evaluates: + * Long_Value__c IN ('one','two') + */ + public ortoo_Criteria inSet( Schema.SObjectField field, Set values ) + { + Contract.requires( field != null, 'inSet called with a null field' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + + criteria.inSet( field, new fflib_Strings( values ) ); return this; } @@ -35,6 +312,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Objects( new List( values ) ) ); } @@ -55,6 +336,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_DateTimes( values ) ); } @@ -75,6 +360,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Dates( values ) ); } @@ -95,6 +384,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Decimals( values ) ); } @@ -115,6 +408,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Doubles( values ) ); } @@ -135,6 +432,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Ids( values ) ); } @@ -155,6 +456,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Integers( values ) ); } @@ -175,6 +480,10 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Longs( values ) ); } @@ -195,9 +504,40 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria inSet( String relatedField, Set values ) { + Contract.requires( relatedField != null, 'inSet called with a null relatedField' ); + Contract.requires( values != null, 'inSet called with a null values' ); + Contract.requires( ! values.isEmpty(), 'inSet called with an empty values' ); + return inSet( relatedField, new fflib_Strings( values ) ); } + /** + * Checks if the given field has a value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Type, new Set{'Customer', 'Competitor', 'Partner'} ) + * + * Evaluates: + * Type NOT IN ('Customer','Competitor','Partner') + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; + } + /** * Checks if the given field has a value that is not in the given set * @@ -215,7 +555,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Objects( new List( values ) ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Objects( new List( values ) ) ); + } + return this; + } + + /** + * Checks if the given field has a DateTime value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.DateTime_Value__c, new Set{ Date.newInstanceGmt( 2020, 01, 02, 11, 20, 00 ), Date.newInstance( 2021, 01, 02, 11, 00, 20 )} ) + * + * Evaluates: + * DateTime_Value__c NOT IN (2021-01-02T11:20:00Z,2021-01-02T11:00:20Z) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -235,7 +609,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_DateTimes( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_DateTimes( values ) ); + } + return this; + } + + /** + * Checks if the given field has a Date value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Date_Value__c, new Set{ Date.newInstance( 2020, 01, 02 ), Date.newInstance( 2021, 01, 02 )} ) + * + * Evaluates: + * Date_Value__c NOT IN (2021-01-02,2021-01-02) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -255,7 +663,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Dates( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Dates( values ) ); + } + return this; + } + + /** + * Checks if the given field has a Decimal value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Decimal_Value__c, new Set{1.1,2.2,3.3} ) + * + * Evaluates: + * Decimal_Value__c NOT IN (1.1,2.2,3.3) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -275,7 +717,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Decimals( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Decimals( values ) ); + } + return this; + } + + /** + * Checks if the given field has a Double value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Double_Value__c, new Set{1.1,2.2,3.3} ) + * + * Evaluates: + * Double_Value__c NOT IN (1.1,2.2,3.3) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -295,7 +771,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Doubles( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Doubles( values ) ); + } + return this; + } + + /** + * Checks if the given field has an Id value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Id, new Set{'0010t00001bH9q2AAC', '0010t00001bH9q2AAB'} ) + * + * Evaluates: + * Id NOT IN ('0010t00001bH9q2AAC','0010t00001bH9q2AAB') + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -315,7 +825,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Ids( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Ids( values ) ); + } + return this; + } + + /** + * Checks if the given field has a Integer value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Integer_Value__c, new Set{1,2,3} ) + * + * Evaluates: + * Integer_Value__c NOT IN (1,2,3) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -335,7 +879,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Integers( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Integers( values ) ); + } + return this; + } + + /** + * Checks if the given field has a Long value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.Long_Value__c, new Set{1,2,3} ) + * + * Evaluates: + * Long_Value__c NOT IN (1,2,3) + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -355,7 +933,41 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Longs( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Longs( values ) ); + } + return this; + } + + /** + * Checks if the given field has a String value that is not in the given set + * + * @param field The field to check the value of + * @param values The values that resolve to 'true' + * + * @return ortoo_Criteria Itself, providing a fluent interface + * + * @example + * new ortoo_Criteria() + * .notInSet( Account.String_Value__c, new Set{'one','two'} ) + * + * Evaluates: + * Long_Value__c NOT IN ('one','two') + */ + public ortoo_Criteria notInSet( Schema.SobjectField field, Set values ) + { + Contract.requires( field != null, 'notInSet called with a null field' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + criteria.notInSet( field, values ); + } + return this; } /** @@ -375,17 +987,24 @@ public inherited sharing virtual class ortoo_Criteria extends fflib_Criteria imp */ public ortoo_Criteria notInSet( String relatedField, Set values ) { - return notInSet( relatedField, new fflib_Strings( values ) ); + Contract.requires( relatedField != null, 'notInSet called with a null relatedField' ); + Contract.requires( values != null, 'notInSet called with a null values' ); + + if ( !values.isEmpty() ) + { + notInSet( relatedField, new fflib_Strings( values ) ); + } + return this; } protected ortoo_Criteria inSet( String relatedField, fflib_Objects values ) { - addEvaluator( new RelatedFieldSetEvaluator( relatedField, fflib_Operator.INx, values ) ); + criteria.addEvaluator( new fflib_Criteria.RelatedFieldSetEvaluator( relatedField, fflib_Operator.INx, values ) ); return this; } protected ortoo_Criteria notInSet( String relatedField, fflib_Objects values ) { - addEvaluator( new RelatedFieldSetEvaluator( relatedField, fflib_Operator.NOT_IN, values ) ); + criteria.addEvaluator( new fflib_Criteria.RelatedFieldSetEvaluator( relatedField, fflib_Operator.NOT_IN, values ) ); return this; } } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls index 12882b3555b..b291384ede0 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls @@ -16,6 +16,21 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'likeString, when called with a field, will add a LIKE to the generated SOQL' ); } + @isTest + private static void likeString_field_whenCalledWithAnEmptyString_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.likeString( Contact.Name, '' ); + Test.stopTest(); + + String expected = ''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'likeString, when called with a field and an empty string, will not add a LIKE to the generated SOQL' ); + } + @isTest private static void likeString_stringName_whenCalled_addsALikeToTheGeneratedSoql() // NOPMD: Test method name format { @@ -31,6 +46,21 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'likeString, when called with a string name for a field will add a LIKE to the generated SOQL' ); } + @isTest + private static void likeString_stringName_whenCalledWithAnEmptyString_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.likeString( 'Contact.Name', '' ); + Test.stopTest(); + + String expected = ''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'likeString, when called with a string name and an empty string, will not add a LIKE to the generated SOQL' ); + } + @isTest private static void inSet_field_stringValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -46,6 +76,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Strings, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_stringValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Strings, will throw an exception' ); + } + @isTest private static void inSet_stringName_stringValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -61,6 +110,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Strings, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_stringValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string name and an empty set of Strings, will throw an exception' ); + } + @isTest private static void inSet_field_longValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -76,6 +144,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Longs, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_longValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Strings, will throw an exception' ); + } + @isTest private static void inSet_stringName_longValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -91,6 +178,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Longs, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_longValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string name and an empty set of Longs, will throw an exception' ); + } + @isTest private static void inSet_field_integerValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -106,6 +212,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Integers, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_integerValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Integers, will throw an exception' ); + } + @isTest private static void inSet_stringName_integerValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -121,6 +246,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Integers, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_integerValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of Integers, will throw an exception' ); + } + @isTest private static void inSet_field_idValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -139,6 +283,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Ids, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_IdValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Ids, will throw an exception' ); + } + @isTest private static void inSet_stringName_idValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -157,6 +320,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Ids, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_IdValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string name and an empty set of Ids, will throw an exception' ); + } + @isTest private static void inSet_field_doubleValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -172,6 +354,24 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Doubles, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_doubleValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Doubles, will throw an exception' ); + } @isTest private static void inSet_stringName_doubleValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -187,6 +387,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Doubles, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_doubleValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of Doubles, will throw an exception' ); + } + @isTest private static void inSet_field_decimalValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -202,6 +421,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Decimals, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_decimalValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Decimal, will throw an exception' ); + } + @isTest private static void inSet_stringName_decimalValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -217,6 +455,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Decimals, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_decimalValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of Decimals, will throw an exception' ); + } + @isTest private static void inSet_field_dateValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -235,6 +492,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of Dates, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_dateValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Dates, will throw an exception' ); + } + @isTest private static void inSet_stringName_dateValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -253,6 +529,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of Dates, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_dateValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of Dates, will throw an exception' ); + } + @isTest private static void inSet_field_dateTimeValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -271,6 +566,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of DateTimes, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_dateTimeValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of DateTime, will throw an exception' ); + } + @isTest private static void inSet_stringName_dateTimeValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -289,6 +603,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of DateTimes, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_dateTimeValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of DateTime, will throw an exception' ); + } + @isTest private static void inSet_field_objectValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -304,6 +637,24 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a field and a set of DateTimes, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_field_objectValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( Account.Name, new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a field and an empty set of Objects, will throw an exception' ); + } @isTest private static void inSet_stringName_objectValues_whenCalled_addsAnInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -319,6 +670,25 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'inSet, when called with a string field name and a set of DateTimes, will add an IN to the generated SOQL' ); } + @isTest + private static void isSet_stringName_objectValues_whenGivenAnEmptySet_throwsAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + Test.startTest(); + String exceptionMessage; + try + { + criteria.inSet( 'Account.Name', new Set() ); + } + catch ( Contract.RequiresException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'inSet called with an empty values', exceptionMessage, 'isSet, when called with a string field name and an empty set of Objects, will throw an exception' ); + } + @isTest private static void notInSet_field_stringValues_whenCalled_addsANotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -334,6 +704,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Strings, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_stringValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Strings, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_stringValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -349,6 +733,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Strings, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_stringValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Strings, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_longValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -364,6 +762,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Longs, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_longValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Longs, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_longValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -379,6 +791,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Longs, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_longValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Longs, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_integerValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -394,6 +820,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Integers, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_integerValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Integers, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_integerValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -409,6 +849,19 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Integers, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_IntegerValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Integer, will not add to the generated SOQL' ); + } @isTest private static void notInSet_field_idValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -427,6 +880,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Ids, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_idValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Ids, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_idValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -445,6 +912,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Ids, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_idValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Ids, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_doubleValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -460,6 +941,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Doubles, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_doubleValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Doubles, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_doubleValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -475,6 +970,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Doubles, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_doubleValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Doubles, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_decimalValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -490,6 +999,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Decimals, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_decimalValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Decimals, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_decimalValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -505,6 +1028,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Decimals, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_decimalValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Decimals, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_dateValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -523,6 +1060,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of Dates, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_dateValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Dates, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_dateValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -541,6 +1092,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of Dates, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_dateValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Dates, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_dateTimeValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -559,6 +1124,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of DateTimes, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_dateTimeValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of DateTime, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_dateTimeValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -577,6 +1156,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of DateTimes, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_dateTimeValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of DateTime, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_field_objectValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -592,6 +1185,20 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a field and a set of DateTimes, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_field_objectValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( Account.Name, new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a field and an empty set of Objects, will not add to the generated SOQL' ); + } + @isTest private static void notInSet_stringName_objectValues_whenCalled_addsNotInToTheGeneratedSoql() // NOPMD: Test method name format { @@ -607,4 +1214,17 @@ private without sharing class ortoo_CriteriaTest System.assertEquals( expected, got, 'notInSet, when called with a string field name and a set of DateTimes, will add NOT IN to the generated SOQL' ); } + @isTest + private static void notInSet_stringName_objectValues_whenGivenAnEmptySet_doesNotAddToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notInSet( 'Account.Name', new Set() ); + Test.stopTest(); + + String got = criteria.toSOQL(); + + System.assertEquals( '', got, 'notInSet, when called with a string name and an empty set of Object, will not add to the generated SOQL' ); + } } \ No newline at end of file From f392e92851bc12a9148ba33de79c495a2c33de1b Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Tue, 15 Feb 2022 16:40:26 +0000 Subject: [PATCH 2/5] Added remaining public methods from fflib_Criteria to ortoo_Criteria Also sorted out the documentation so it is consistent --- .../fflib-extension/ortoo_Criteria.cls | 647 ++++++++++++++---- 1 file changed, 512 insertions(+), 135 deletions(-) diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls index 267a518a099..fb0ecfd84e1 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls @@ -7,26 +7,437 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria { fflib_Criteria criteria; + // TODO: write tests for SOQL generation of: + // orCriteria + // andCriteria + // andOrCriteria + // andAndCriteria + // formulaCriteria + // + // equalTo + // notEqualTo + // greaterOrEqualTo + // greaterThan + // lessOrEqualTo + // lessThan + // + // TODO: consider a test for filtering of records? + // TODO: change SObjects2 to allow ortoo_Criteria - maybe define an interface instead + public ortoo_Criteria() { criteria = new fflib_Criteria(); } + /** + * Generates the SOQL equivalent of the configured criteria + * + * @return String The "where" part in the SOQL statement + */ public String toSOQL() { return criteria.toSOQL(); } - // TODO: add remaining public methods from fflib_Criteria - // TODO: change SObjects2 to allow ortoo_Criteria - maybe define an interface instead + /** + * Evaluates the given object against the configured criteria + * + * @param Object The object to evaluate + * @return Boolean Statement of whether the record matches the criteria + */ + public Boolean evaluate( Object record ) + { + Contract.requires( record != null, 'evaluate called with a null record' ); + return criteria.evaluate( record ); + } /** - * Checks if the given field has a value 'like' that given + * Changes the default comparator for each criteria to OR * - * @param field The field to check the value of - * @param values The value that resolve to 'true' + * @return ortoo_Criteria Itself, allowing for a fluent interface * - * @return ortoo_Criteria Itself, providing a fluent interface + * @example + * new ortoo_Criteria() + * .orCriteria() + * .equalTo(Account.Name, 'Example') + * .equalTo(Account.AccountNumber, '1234567') + * + * Evaluates: + * Name = 'Example' OR AccountNumber = '1234567' + */ + public ortoo_Criteria orCriteria() + { + criteria.orCriteria(); + return this; + } + + /** + * Changes the default comparator for each criteria to AND + * + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .andCriteria() + * .equalTo(Account.Name, 'Example') + * .equalTo(Account.AccountNumber, '1234567') + * + * Evaluates: + * Name = 'Example' AND AccountNumber = '1234567' + */ + public ortoo_Criteria andCriteria() + { + criteria.andCriteria(); + return this; + } + + /** + * Adds a sub-criteria with OR comparator + * + * @param ortoo_Criteria The condition of the sub criteria + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .equalTo(Account.Name, 'Example') + * .addOrCriteria( + * new ortoo_Criteria() + * .equalTo(Account.AccountNumber, '0001') + * .equalTo(Account.AccountNumber, '0002')) + * + * Evaluates: + * Account.Name = 'Example' AND (Account.AccountNumber = '0001' OR Account.AccountNumber = '0002') + */ + public ortoo_Criteria addOrCriteria( ortoo_Criteria subCriteria ) + { + Contract.requires( subCriteria != null, 'addOrCriteria called with a null subCriteria' ); + Contract.requires( subCriteria.criteria != null, 'addOrCriteria called with a subCriteria that has no criteria defined' ); + + criteria.addOrCriteria( subCriteria.criteria ); + return this; + } + + /** + * Adds a sub-criteria with AND comparator + * + * @param ortoo_Criteria The condition of the sub criteria + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .orCriteria() + * .equalTo(Account.Name, 'Example') + * .addAndCriteria( + * new ortoo_Criteria() + * .equalTo(Account.AccountNumber, '0001') + * .equalTo(Account.ShippingCountry, 'USA')) + * + * Evaluates: + * Name = 'Example' OR (AccountNumber = '0001' AND ShippingCountry = 'USA') + */ + public ortoo_Criteria addAndCriteria( ortoo_Criteria subCriteria ) + { + Contract.requires( subCriteria != null, 'addAndCriteria called with a null subCriteria' ); + Contract.requires( subCriteria.criteria != null, 'addAndCriteria called with a subCriteria that has no criteria defined' ); + + criteria.addAndCriteria( subCriteria.criteria ); + return this; + } + + /** + * Defines a formual within which the specified criteria should be evaluated. + * + * @param String The formula string using numbers, AND, OR and parenthesis + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .formulaCriteria('(1 OR 2) AND 3') + * .equalTo(Account.AccountNumber, '0001') + * .equalTo(Account.AccountNumber, '0002') + * .equalTo(Account.ShippingCountry, 'USA')) + * + * Evaluates: + * (AccountNumber = '0001' OR AccountNumber = '0001') AND ShippingCountry = 'USA' + */ + public ortoo_Criteria formulaCriteria( String formula ) + { + Contract.requires( String.isNotBlank( formula ), 'formulaCriteria called with a blank formula' ); + + criteria.formulaCriteria( formula ); + return this; + } + + /** + * Add an equal to criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .equalTo(Account.Name, 'Example') + * + * Evaluates: + * Name = 'Example' + */ + public ortoo_Criteria equalTo( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'equalTo called with a null field' ); + + criteria.equalTo( field, value ); + return this; + } + + /** + * Add an equal to criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .equalTo('Account.Name', 'Example') + * + * Evaluates: + * Account.Name = 'Example' + */ + public ortoo_Criteria equalTo( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'equalTo called with a null relatedField' ); + + criteria.equalTo( relatedField, value ); + return this; + } + + /** + * Add a not equal to criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .notEqualTo(Account.Name, 'Example') + * + * Evaluates: + * Name != 'Example' + */ + public ortoo_Criteria notEqualTo( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'notEqualTo called with a null field' ); + + criteria.notEqualTo( field, value ); + return this; + } + + /** + * Add a not equal to criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .notEqualTo('Account.Name', 'Example') + * + * Evaluates: + * Account.Name != 'Example' + */ + public ortoo_Criteria notEqualTo( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'notEqualTo called with a null relatedField' ); + + criteria.notEqualTo( relatedField, value ); + return this; + } + + /** + * Add a greater than or equal to criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .greaterOrEqualTo(Account.Numeric_Field__c, 10) + * + * Evaluates: + * Numeric_Field__c >= 10 + */ + public ortoo_Criteria greaterOrEqualTo( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'greaterOrEqualTo called with a null field' ); + + criteria.greaterOrEqualTo( field, value ); + return this; + } + + /** + * Add a greater than or equal to criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .greaterOrEqualTo('Account.Numeric_Field__c', 10 ) + * + * Evaluates: + * Account.Numeric_Field__c >= 10 + */ + public ortoo_Criteria greaterOrEqualTo( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'greaterOrEqualTo called with a null relatedField' ); + + criteria.greaterOrEqualTo( relatedField, value ); + return this; + } + + /** + * Add a greater than criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .greaterThan(Account.Numeric_Field__c, 10) + * + * Evaluates: + * Numeric_Field__c > 10 + */ + public ortoo_Criteria greaterThan( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'greaterThan called with a null field' ); + + criteria.greaterThan( field, value ); + return this; + } + + /** + * Add a greater than criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .greaterThan('Account.Numeric_Field__c', 10 ) + * + * Evaluates: + * Account.Numeric_Field__c > 10 + */ + public ortoo_Criteria greaterThan( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'greaterThan called with a null relatedField' ); + + criteria.greaterThan( relatedField, value ); + return this; + } + + /** + * Add a less than or equal to criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .lessOrEqualTo(Account.Name, 10 ) + * + * Evaluates: + * Numeric_Field__c <= 10 + */ + public ortoo_Criteria lessOrEqualTo( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'lessOrEqualTo called with a null field' ); + + criteria.lessOrEqualTo( field, value ); + return this; + } + + /** + * Add a less than or equal to criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .lessOrEqualTo('Account.Numeric_Field__c', 10 ) + * + * Evaluates: + * Account.Numeric_Field__c <= 10 + */ + public ortoo_Criteria lessOrEqualTo( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'lessOrEqualTo called with a null relatedField' ); + + criteria.lessOrEqualTo( relatedField, value ); + return this; + } + + /** + * Add a less than criteria comparing a fields value to a given value + * + * @param Schema.SObjectField The sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .lessThan(Account.Numeric_Field__c, 10 ) + * + * Evaluates: + * Numeric_Field__c < 10 + */ + public ortoo_Criteria lessThan( Schema.SObjectField field, Object value ) + { + Contract.requires( field != null, 'lessThan called with a null field' ); + + criteria.lessThan( field, value ); + return this; + } + + /** + * Add a less than criteria comparing a fields value to a given value + * + * @param String The name of the sObjectField to evaluate + * @param Object The value to be compared to the fields value + * @return ortoo_Criteria Itself, allowing for a fluent interface + * + * @example + * new ortoo_Criteria() + * .lessThan('Account.Numeric_Field__c', 10 ) + * + * Evaluates: + * Account.Numeric_Field__c < 10 + */ + public ortoo_Criteria lessThan( String relatedField, Object value ) + { + Contract.requires( relatedField != null, 'lessThan called with a null relatedField' ); + + criteria.lessThan( relatedField, value ); + return this; + } + + /** + * Checks if the given field has a value 'like' that given + * + * @param Schema.SobjectField The field to check the value of + * @param String The value that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -38,6 +449,7 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria public ortoo_Criteria likeString( Schema.SObjectField field, String value ) { Contract.requires( field != null, 'likeString called with a null field' ); + if ( ! String.isEmpty( value ) ) { criteria.addEvaluator( new fflib_Criteria.FieldEvaluator( field, fflib_Operator.LIKEx, value ) ); @@ -48,9 +460,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a value 'like' that given * - * @param relatedField The name of the to check the value of - * @param values The value that resolve to 'true' - * + * @param String The name of the to check the value of + * @param String The value that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -63,6 +474,7 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria public ortoo_Criteria likeString( String relatedField, String value ) { Contract.requires( relatedField != null, 'likeString called with a null relatedField' ); + if ( ! String.isEmpty( value ) ) { criteria.addEvaluator( new fflib_Criteria.RelatedFieldEvaluator( relatedField, fflib_Operator.LIKEx, value ) ); @@ -73,10 +485,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -98,10 +509,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a DateTime value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -123,10 +533,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Date value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -148,10 +557,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Decimal value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -173,10 +581,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Double value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -198,10 +605,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has an Id value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -223,10 +629,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Integer value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -248,10 +653,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Long value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -273,10 +677,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a String value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -298,9 +701,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -322,9 +724,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a DateTime value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -346,9 +747,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Date value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -370,9 +770,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Decimal value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -394,9 +793,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Double value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -418,9 +816,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has an Id value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -442,9 +839,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Integer value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -466,9 +862,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Long value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -490,9 +885,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a String value in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -514,10 +908,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -541,9 +934,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -568,10 +960,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a DateTime value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -595,9 +986,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a DateTime value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -622,10 +1012,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Date value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -649,9 +1038,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Date value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -676,10 +1064,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Decimal value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -703,9 +1090,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Decimal value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -730,10 +1116,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Double value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -757,9 +1142,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Double value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -784,10 +1168,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has an Id value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -811,9 +1194,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has an Id value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -838,10 +1220,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Integer value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -865,9 +1246,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Integer value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -892,10 +1272,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Long value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -919,9 +1298,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a Long value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The name of the field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -946,10 +1324,9 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a String value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * - * @return ortoo_Criteria Itself, providing a fluent interface + * @param Schema.SobjectField The field to check the value of + * @param Set The values that resolve to 'true' + * @return ortoo_Criteria Itself, providing a fluent interface * * @example * new ortoo_Criteria() @@ -973,9 +1350,8 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria /** * Checks if the given field has a String value that is not in the given set * - * @param field The field to check the value of - * @param values The values that resolve to 'true' - * + * @param String The field to check the value of + * @param Set The values that resolve to 'true' * @return ortoo_Criteria Itself, providing a fluent interface * * @example @@ -1002,6 +1378,7 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria criteria.addEvaluator( new fflib_Criteria.RelatedFieldSetEvaluator( relatedField, fflib_Operator.INx, values ) ); return this; } + protected ortoo_Criteria notInSet( String relatedField, fflib_Objects values ) { criteria.addEvaluator( new fflib_Criteria.RelatedFieldSetEvaluator( relatedField, fflib_Operator.NOT_IN, values ) ); From 66303ffe46bfc344a0e8b51a10d8af7cfbcd81e1 Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Wed, 16 Feb 2022 09:13:46 +0000 Subject: [PATCH 3/5] Minor improvement to uriUtils test to check console.error output --- .../default/lwc/uriUtils/__tests__/uriUtils.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/framework/default/ortoo-core/default/lwc/uriUtils/__tests__/uriUtils.test.js b/framework/default/ortoo-core/default/lwc/uriUtils/__tests__/uriUtils.test.js index 85743179dd1..2186ea1707e 100644 --- a/framework/default/ortoo-core/default/lwc/uriUtils/__tests__/uriUtils.test.js +++ b/framework/default/ortoo-core/default/lwc/uriUtils/__tests__/uriUtils.test.js @@ -164,6 +164,8 @@ describe( 'getUriFragmentAsObject', () => { }) it( 'will skip values that do not decode properly', () => { + console.error = jest.fn() + location.hash = 'property1=%22value1%22&invalid=%22incompleteJson&property2=%22value2%22'; const expected = { @@ -173,6 +175,8 @@ describe( 'getUriFragmentAsObject', () => { const got = UriUtils.getUriFragmentAsObject(); expect( got ).toEqual( expected ); + expect( console.error ).toHaveBeenCalled(); + expect( console.error ).toHaveBeenCalledWith( 'Invalid parameter value in URI fragment' ); }) }); From 746fc5460af711762c981e68a4041c7138cb4dd7 Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Wed, 16 Feb 2022 11:56:12 +0000 Subject: [PATCH 4/5] Added a lot of tests for ortoo_Criteria Switched fflib_SObjects2 over to use interface for criteria, allowing use of ortoo_Criteria Fixed documentation errors on ortoo_Criteria --- .../classes/domains/fflib_SObjects2.cls | 2 +- .../fflib-extension/ortoo_Criteria.cls | 23 +- .../tests/ortoo_CriteriaTest.cls | 516 ++++++++++++++++++ 3 files changed, 520 insertions(+), 21 deletions(-) diff --git a/framework/default/fflib-apex-extensions/default/classes/domains/fflib_SObjects2.cls b/framework/default/fflib-apex-extensions/default/classes/domains/fflib_SObjects2.cls index cb93eb772c6..e379261dbdc 100644 --- a/framework/default/fflib-apex-extensions/default/classes/domains/fflib_SObjects2.cls +++ b/framework/default/fflib-apex-extensions/default/classes/domains/fflib_SObjects2.cls @@ -120,7 +120,7 @@ public virtual class fflib_SObjects2 * * @return Return the SObject records contained in the domain matching the criteria */ - public virtual List getRecords(fflib_Criteria criteria) + public virtual List getRecords(fflib_Criteria.Evaluator criteria) { List result = new List(); for (SObject record : getRecords()) diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls index fb0ecfd84e1..77978eaccb1 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_Criteria.cls @@ -7,23 +7,6 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria { fflib_Criteria criteria; - // TODO: write tests for SOQL generation of: - // orCriteria - // andCriteria - // andOrCriteria - // andAndCriteria - // formulaCriteria - // - // equalTo - // notEqualTo - // greaterOrEqualTo - // greaterThan - // lessOrEqualTo - // lessThan - // - // TODO: consider a test for filtering of records? - // TODO: change SObjects2 to allow ortoo_Criteria - maybe define an interface instead - public ortoo_Criteria() { criteria = new fflib_Criteria(); @@ -106,7 +89,7 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria * .equalTo(Account.AccountNumber, '0002')) * * Evaluates: - * Account.Name = 'Example' AND (Account.AccountNumber = '0001' OR Account.AccountNumber = '0002') + * Name = 'Example' AND (AccountNumber = '0001' OR AccountNumber = '0002') */ public ortoo_Criteria addOrCriteria( ortoo_Criteria subCriteria ) { @@ -155,10 +138,10 @@ public inherited sharing virtual class ortoo_Criteria implements ISearchCriteria * .formulaCriteria('(1 OR 2) AND 3') * .equalTo(Account.AccountNumber, '0001') * .equalTo(Account.AccountNumber, '0002') - * .equalTo(Account.ShippingCountry, 'USA')) + * .equalTo(Account.ShippingCountry, 'USA') * * Evaluates: - * (AccountNumber = '0001' OR AccountNumber = '0001') AND ShippingCountry = 'USA' + * (AccountNumber = '0001' OR AccountNumber = '0002') AND ShippingCountry = 'USA' */ public ortoo_Criteria formulaCriteria( String formula ) { diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls index b291384ede0..8e4cabf699f 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls @@ -1,6 +1,522 @@ @isTest private without sharing class ortoo_CriteriaTest { + @isTest + private static void byDefault_joinsCriteriaWithAnd() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .equalTo(Account.Name, 'Example') + .equalTo(Account.AccountNumber, '1234567') + .toSoql(); + Test.stopTest(); + + String expected = 'Name=\'Example\' ANd AccountNumber=\'1234567\''; + + System.assertEquals( expected, got, 'by default, will join the generated SOQL with AND' ); + } + + @isTest + private static void orCriteria_whenGivenCriteria_resultsInOrsInTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .orCriteria() + .equalTo(Account.Name, 'Example') + .equalTo(Account.AccountNumber, '1234567') + .toSoql(); + Test.stopTest(); + + String expected = 'Name=\'Example\' OR AccountNumber=\'1234567\''; + + System.assertEquals( expected, got, 'orCriteria, when given further criteria, will join the generated SOQL with OR' ); + } + + @isTest + private static void andCriteria_whenGivenCriteria_resultsInAndsInTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .andCriteria() + .equalTo(Account.Name, 'Example') + .equalTo(Account.AccountNumber, '1234567') + .toSoql(); + Test.stopTest(); + + String expected = 'Name=\'Example\' AND AccountNumber=\'1234567\''; + + System.assertEquals( expected, got, 'andCriteria, when given further criteria, will join the generated SOQL with AND' ); + } + + @isTest + private static void andOrCriteria_whenGivenSubCriteria_addsTheSubCriteriaSetAsOr() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .equalTo(Account.Name, 'Example') + .addOrCriteria( + new ortoo_Criteria() + .equalTo(Account.AccountNumber, '0001') + .equalTo(Account.AccountNumber, '0002')) + .toSoql(); + Test.stopTest(); + + String expected = 'Name=\'Example\' AND (AccountNumber=\'0001\' OR AccountNumber=\'0002\')'; + + System.assertEquals( expected, got, 'andOrCriteria, when given sub criteria, will add the subcriteria set as OR criteria' ); + } + + @isTest + private static void andAndCriteria_whenGivenSubCriteria_addsTheSubCriteriaSetAsAnd() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .equalTo(Account.Name, 'Example') + .addAndCriteria( + new ortoo_Criteria() + .equalTo(Account.AccountNumber, '0001') + .equalTo(Account.AccountNumber, '0002')) + .toSoql(); + Test.stopTest(); + + String expected = 'Name=\'Example\' AND (AccountNumber=\'0001\' AND AccountNumber=\'0002\')'; + + System.assertEquals( expected, got, 'andAndCriteria, when given sub criteria, will add the subcriteria set as AND criteria' ); + } + + @isTest + private static void formulaCriteria_whenGivenCriteria_addsTheCriteriaInLineWithTheFormula() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .formulaCriteria('(1 OR 2) AND 3') + .equalTo(Account.AccountNumber, '0001') + .equalTo(Account.AccountNumber, '0002') + .equalTo(Account.ShippingCountry, 'USA') + .toSoql(); + Test.stopTest(); + + String expected = '(AccountNumber=\'0001\' OR AccountNumber=\'0002\') AND ShippingCountry=\'USA\''; + + System.assertEquals( expected, got, 'formulaCriteria, when given futher criteria, will add the criteria in line with the formula' ); + } + + @isTest + private static void formulaCriteria_whenGivenRepeatedReferences_addsTheCriteriaInLineWithTheFormula() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String got = criteria + .formulaCriteria('(1 OR 2) AND (1 OR 3)') + .equalTo(Account.AccountNumber, '0001') + .equalTo(Account.AccountNumber, '0002') + .equalTo(Account.ShippingCountry, 'USA') + .toSoql(); + Test.stopTest(); + + String expected = '(AccountNumber=\'0001\' OR AccountNumber=\'0002\') AND (AccountNumber=\'0001\' OR ShippingCountry=\'USA\')'; + + System.assertEquals( expected, got, 'formulaCriteria, when given repeated references in the formula criteria, will add the repeated references' ); + } + + @isTest + private static void formulaCriteria_whenGivenFewerCriteriaThanReferenced_willThrowAnException() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + String exceptionMessage; + try + { + String got = criteria + .formulaCriteria('(1 OR 2) AND 3') + .equalTo(Account.AccountNumber, '0001') + .equalTo(Account.AccountNumber, '0002') + .toSoql(); + } + catch ( fflib_Criteria.CriteriaException e ) + { + exceptionMessage = e.getMessage(); + } + Test.stopTest(); + + Amoss_Asserts.assertContains( 'Expected a formula expression with number: 3', exceptionMessage, 'formulaCriteria, when given a formula and fewer criteria than referenced, will throw an exception' ); + } + + @isTest + private static void equalTo_field_whenGivenAString_addsAnEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.equalTo( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'equalTo, when called with a field and a string value, will add a = to the generated SOQL' ); + } + + @isTest + private static void equalTo_field_whenGivenANumber_addsAnEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.equalTo( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'equalTo, when called with a field and a numeric value, will add a = to the generated SOQL' ); + } + + @isTest + private static void equalTo_stringName_whenGivenAString_addsAnEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.equalTo( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'equalTo, when called with a string field name and a string value, will add a = to the generated SOQL' ); + } + + @isTest + private static void equalTo_stringName_whenGivenANumber_addsAnEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.equalTo( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'equalTo, when called with a string field name and a numeric value, will add a = to the generated SOQL' ); + } + + @isTest + private static void notEqualTo_field_whenGivenAString_addsANotEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notEqualTo( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name!=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'notEqualTo, when called with a field and a string value, will add a != to the generated SOQL' ); + } + + @isTest + private static void notEqualTo_field_whenGivenANumber_addsANotEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notEqualTo( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name!=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'notEqualTo, when called with a field and a numeric value, will add a != to the generated SOQL' ); + } + + @isTest + private static void notEqualTo_stringName_whenGivenAString_addsANotEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notEqualTo( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name!=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'notEqualTo, when called with a string field name and a string value, will add a != to the generated SOQL' ); + } + + @isTest + private static void notEqualTo_stringName_whenGivenANumber_addsANotEqualsToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.notEqualTo( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name!=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'notEqualTo, when called with a string field name and a numeric value, will add a != to the generated SOQL' ); + } + + @isTest + private static void greaterOrEqualTo_field_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterOrEqualTo( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name>=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterOrEqualTo, when called with a field and a string value, will add a >= to the generated SOQL' ); + } + + @isTest + private static void greaterOrEqualTo_field_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterOrEqualTo( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name>=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterOrEqualTo, when called with a field and a numeric value, will add a >= to the generated SOQL' ); + } + + @isTest + private static void greaterOrEqualTo_stringName_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterOrEqualTo( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name>=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterOrEqualTo, when called with a string field name and a string value, will add a >= to the generated SOQL' ); + } + + @isTest + private static void greaterOrEqualTo_stringName_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterOrEqualTo( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name>=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterOrEqualTo, when called with a string field name and a numeric value, will add a >= to the generated SOQL' ); + } + + @isTest + private static void greaterThan_field_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterThan( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name>\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterThan, when called with a field and a string value, will add a > to the generated SOQL' ); + } + + @isTest + private static void greaterThan_field_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterThan( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name>12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterThan, when called with a field and a numeric value, will add a > to the generated SOQL' ); + } + + @isTest + private static void greaterThan_stringName_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterThan( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name>\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterThan, when called with a string field name and a string value, will add a > to the generated SOQL' ); + } + + @isTest + private static void greaterThan_stringName_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.greaterThan( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name>12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'greaterThan, when called with a string field name and a numeric value, will add a > to the generated SOQL' ); + } + + @isTest + private static void lessOrEqualTo_field_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessOrEqualTo( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name<=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessOrEqualTo, when called with a field and a string value, will add a <= to the generated SOQL' ); + } + + @isTest + private static void lessOrEqualTo_field_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessOrEqualTo( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name<=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessOrEqualTo, when called with a field and a numeric value, will add a <= to the generated SOQL' ); + } + + @isTest + private static void lessOrEqualTo_stringName_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessOrEqualTo( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name<=\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessOrEqualTo, when called with a string field name and a string value, will add a <= to the generated SOQL' ); + } + + @isTest + private static void lessOrEqualTo_stringName_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessOrEqualTo( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name<=12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessOrEqualTo, when called with a string field name and a numeric value, will add a <= to the generated SOQL' ); + } + + + @isTest + private static void lessThan_field_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessThan( Contact.Name, 'contactName' ); + Test.stopTest(); + + String expected = 'Name<\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessThan, when called with a field and a string value, will add a < to the generated SOQL' ); + } + + @isTest + private static void lessThan_field_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessThan( Contact.Name, 12 ); + Test.stopTest(); + + String expected = 'Name<12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessThan, when called with a field and a numeric value, will add a < to the generated SOQL' ); + } + + @isTest + private static void lessThan_stringName_whenGivenAString_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessThan( 'Contact.Name', 'contactName' ); + Test.stopTest(); + + String expected = 'Contact.Name<\'contactName\''; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessThan, when called with a string field name and a string value, will add a < to the generated SOQL' ); + } + + @isTest + private static void lessThan_stringName_whenGivenANumber_addsAClauseToTheGeneratedSoql() // NOPMD: Test method name format + { + ortoo_Criteria criteria = new ortoo_Criteria(); + + Test.startTest(); + criteria.lessThan( 'Contact.Name', 12 ); + Test.stopTest(); + + String expected = 'Contact.Name<12'; + String got = criteria.toSOQL(); + + System.assertEquals( expected, got, 'lessThan, when called with a string field name and a numeric value, will add a < to the generated SOQL' ); + } + @isTest private static void likeString_field_whenCalled_addsALikeToTheGeneratedSoql() // NOPMD: Test method name format { From 018946ef8a2eb08cdfbd40846a952599ee37a65a Mon Sep 17 00:00:00 2001 From: Robert Baillie Date: Wed, 16 Feb 2022 12:02:06 +0000 Subject: [PATCH 5/5] Fixed typo --- .../classes/fflib-extension/tests/ortoo_CriteriaTest.cls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls index 8e4cabf699f..893a3afa3c9 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_CriteriaTest.cls @@ -13,7 +13,7 @@ private without sharing class ortoo_CriteriaTest .toSoql(); Test.stopTest(); - String expected = 'Name=\'Example\' ANd AccountNumber=\'1234567\''; + String expected = 'Name=\'Example\' AND AccountNumber=\'1234567\''; System.assertEquals( expected, got, 'by default, will join the generated SOQL with AND' ); }