Skip to content

Commit

Permalink
Merge pull request #1 from OrtooApps/feature/include-mocks-and-ext
Browse files Browse the repository at this point in the history
Feature/include mocks and ext
  • Loading branch information
rob-baillie-ortoo committed May 4, 2022
2 parents 869710a + 1a7964e commit 573efa3
Show file tree
Hide file tree
Showing 125 changed files with 19,335 additions and 39 deletions.
6 changes: 1 addition & 5 deletions sfdx-source/apex-common/main/classes/fflib_Application.cls
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,7 @@ public virtual class fflib_Application
}

try {
if ( !serviceInterfaceName.endsWith( 'ILoggerService' ) )
{
LoggerService.log( LoggerService.LEVEL.INFO, 'Using default implementation ' + defaultServiceName + ' for ' + serviceInterfaceName );
}

System.debug( LoggingLevel.INFO, 'Using default implementation ' + defaultServiceName + ' for ' + serviceInterfaceName );
return defaultServiceType.newInstance();
}
catch ( Exception e ) {
Expand Down
4 changes: 2 additions & 2 deletions sfdx-source/apex-common/main/classes/fflib_QueryFactory.cls
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
}
set;
}
private ISearchCriteria conditionCriteria;
private fflib_ISoqlable conditionCriteria;
private Integer limitCount;
private Integer offsetCount;
private List<Ordering> order;
Expand Down Expand Up @@ -347,7 +347,7 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
/**
* @param conditionExpression Sets the WHERE clause to the string provided by the given ISearchCriteria
**/
public fflib_QueryFactory setCondition(ISearchCriteria criteria){
public fflib_QueryFactory setCondition(fflib_ISoqlable criteria){
this.conditionCriteria = criteria;
this.conditionExpression = null;
return this;
Expand Down
73 changes: 41 additions & 32 deletions sfdx-source/apex-common/test/classes/fflib_QueryFactoryTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -72,56 +72,61 @@ private class fflib_QueryFactoryTest {
}

@isTest
static void iSearchCriteriaCondition(){
static void iSoqlableCondition(){

String whereClause = 'name = \'test\'';

Amoss_Instance searchCriteriaController = new Amoss_Instance( ISearchCriteria.class );
searchCriteriaController
.when( 'toSoql' )
.returns( whereClause );
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISoqlable mockSoqlable = (fflib_ISoqlable)mocks.mock( fflib_ISoqlable.class );

mocks.startStubbing();
mocks.when( mockSoqlable.toSOQL() ).thenReturn( whereClause );
mocks.stopStubbing();

fflib_QueryFactory qf = new fflib_QueryFactory(Contact.SObjectType);
qf.selectField('name');
qf.setCondition( (ISearchCriteria)searchCriteriaController.getDouble() );
qf.setCondition( mockSoqlable );

System.assertEquals( whereClause, qf.getCondition(), 'setCondition, when given an ISearchCriteria, will set the condition based on the criteria' );
System.assertEquals( whereClause, qf.getCondition(), 'setCondition, when given an fflib_ISoqlable, will set the condition based on the criteria' );

String query = qf.toSOQL();
System.assert( query.endsWith('WHERE name = \'test\''),'Query should have ended with a filter on name, got: '+query);

((fflib_ISoqlable)mocks.verify( mockSoqlable, mocks.atLeast(1))).toSoql();
}

@isTest
static void iSearchCriteriaCondition_notEvaluatedOnSet(){
static void iSoqlableCondition_notEvaluatedOnSet(){

Amoss_Instance searchCriteriaController = new Amoss_Instance( ISearchCriteria.class );
searchCriteriaController
.expectsNoCalls();
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISoqlable mockSoqlable = (fflib_ISoqlable)mocks.mock( fflib_ISoqlable.class );

fflib_QueryFactory qf = new fflib_QueryFactory(Contact.SObjectType);
qf.selectField('name');
qf.setCondition( (ISearchCriteria)searchCriteriaController.getDouble() );
qf.setCondition( mockSoqlable );

searchCriteriaController.verify();
((fflib_ISoqlable)mocks.verify( mockSoqlable, mocks.never())).toSoql();
}

@isTest
static void iSearchCriteriaCondition_isEvaluatedOnGet(){
static void iSoqlableCondition_isEvaluatedOnGet(){

String whereClause = 'name = \'test\'';

Amoss_Instance searchCriteriaController = new Amoss_Instance( ISearchCriteria.class );
searchCriteriaController
.when( 'toSoql' )
.returns( whereClause );
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISoqlable mockSoqlable = (fflib_ISoqlable)mocks.mock( fflib_ISoqlable.class );

mocks.startStubbing();
mocks.when( mockSoqlable.toSOQL() ).thenReturn( whereClause );
mocks.stopStubbing();

fflib_QueryFactory qf = new fflib_QueryFactory(Contact.SObjectType);
qf.selectField('name');
qf.setCondition( (ISearchCriteria)searchCriteriaController.getDouble() );
qf.setCondition( mockSoqlable );

qf.getCondition();

searchCriteriaController.verify();
((fflib_ISoqlable)mocks.verify( mockSoqlable, mocks.times(1))).toSoql();
}

@isTest
Expand All @@ -130,17 +135,19 @@ private class fflib_QueryFactoryTest {
String stringWhereClause = 'name = \'string\'';
String criteriaWhereClause = 'name = \'criteria\'';

Amoss_Instance searchCriteriaController = new Amoss_Instance( ISearchCriteria.class );
searchCriteriaController
.when( 'toSoql' )
.returns( criteriaWhereClause );
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISoqlable mockSoqlable = (fflib_ISoqlable)mocks.mock( fflib_ISoqlable.class );

mocks.startStubbing();
mocks.when( mockSoqlable.toSOQL() ).thenReturn( criteriaWhereClause );
mocks.stopStubbing();

fflib_QueryFactory qf = new fflib_QueryFactory(Contact.SObjectType);
qf.selectField('name');
qf.setCondition( stringWhereClause );
qf.setCondition( (ISearchCriteria)searchCriteriaController.getDouble() );
qf.setCondition( mockSoqlable );

System.assertEquals( criteriaWhereClause, qf.getCondition(), 'setCondition, when given a string then a ISearchCriteria, will set the condition based on the last thing - the criteria' );
System.assertEquals( criteriaWhereClause, qf.getCondition(), 'setCondition, when given a string then a fflib_ISoqlable, will set the condition based on the last thing - the criteria' );
}

@isTest
Expand All @@ -149,17 +156,19 @@ private class fflib_QueryFactoryTest {
String stringWhereClause = 'name = \'string\'';
String criteriaWhereClause = 'name = \'criteria\'';

Amoss_Instance searchCriteriaController = new Amoss_Instance( ISearchCriteria.class );
searchCriteriaController
.when( 'toSoql' )
.returns( criteriaWhereClause );
fflib_ApexMocks mocks = new fflib_ApexMocks();
fflib_ISoqlable mockSoqlable = (fflib_ISoqlable)mocks.mock( fflib_ISoqlable.class );

mocks.startStubbing();
mocks.when( mockSoqlable.toSOQL() ).thenReturn( criteriaWhereClause );
mocks.stopStubbing();

fflib_QueryFactory qf = new fflib_QueryFactory(Contact.SObjectType);
qf.selectField('name');
qf.setCondition( (ISearchCriteria)searchCriteriaController.getDouble() );
qf.setCondition( mockSoqlable );
qf.setCondition( stringWhereClause );

System.assertEquals( stringWhereClause, qf.getCondition(), 'setCondition, when given a ISearchCriteria then string, will set the condition based on the last thing - the string' );
System.assertEquals( stringWhereClause, qf.getCondition(), 'setCondition, when given a fflib_ISoqlable then string, will set the condition based on the last thing - the string' );
}

@isTest
Expand Down
19 changes: 19 additions & 0 deletions sfdx-source/apex-mocks/fflib_Answer.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright (c) 2017 FinancialForce.com, inc. All rights reserved.
*/

/**
* Interface for the answering framework.
* This interface must be implemented inside the test class and implement the call back method answer.
* @group Core
*/
public interface fflib_Answer
{
/**
* Method to be implemented in the test class to implement the call back method.
* @param invocation The invocation on the mock.
* @throws The exception to be thrown.
* @return The value to be returned.
*/
Object answer(fflib_InvocationOnMock invocation);
}
5 changes: 5 additions & 0 deletions sfdx-source/apex-mocks/fflib_Answer.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
<status>Active</status>
</ApexClass>
105 changes: 105 additions & 0 deletions sfdx-source/apex-mocks/fflib_AnyOrder.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Copyright (c) 2017 FinancialForce.com, inc. All rights reserved.
*/

/**
* 'Classic' invocation verifier - checks that a method was called with the given arguments the expected number of times.
* The order of method calls is not important.
* @group Core
*/
public class fflib_AnyOrder extends fflib_MethodVerifier
{
/*
* Verifies a method was invoked the expected number of times, with the expected arguments.
* @param qualifiedMethod The method to be verified.
* @param methodArg The arguments of the method that needs to be verified.
* @param verificationMode The verification mode that holds the setting about how the verification should be performed.
*/
protected override void verify(
fflib_QualifiedMethod qm,
fflib_MethodArgValues expectedArguments,
fflib_VerificationMode verificationMode)
{
List<fflib_IMatcher> expectedMatchers = fflib_Match.Matching ? fflib_Match.getAndClearMatchers(expectedArguments.argValues.size()) : null;
List<fflib_MethodArgValues> actualArguments = fflib_MethodCountRecorder.getMethodArgumentsByTypeName().get(qm);

Integer methodCount = getMethodCount(expectedArguments, expectedMatchers, actualArguments);

String qualifier = '';
Integer expectedCount = null;

if((verificationMode.VerifyMin == verificationMode.VerifyMax) && methodCount != verificationMode.VerifyMin)
{
expectedCount = verificationMode.VerifyMin;
}
else if (verificationMode.VerifyMin != null && verificationMode.VerifyMin > methodCount)
{
expectedCount = verificationMode.VerifyMin;
qualifier = ' or more times';
}
else if (verificationMode.VerifyMax != null && verificationMode.VerifyMax < methodCount)
{
expectedCount = verificationMode.VerifyMax;
qualifier = ' or fewer times';
}

if (expectedCount != null)
{
throwException(qm, '', expectedCount, qualifier, methodCount, verificationMode.CustomAssertMessage, expectedArguments, expectedMatchers, actualArguments);
}
}

private Integer getMethodCount(fflib_MethodArgValues methodArg, List<fflib_IMatcher> matchers, List<fflib_MethodArgValues> methodArgs)
{
Integer retval = 0;

if (methodArgs != null)
{
if (matchers != null)
{
for (fflib_MethodArgValues args : methodArgs)
{
if (fflib_Match.matchesAllArgs(args, matchers))
{
capture(matchers);
retval ++;
}
}
}
else
{
return countCalls(methodArgs, methodArg);
}
}

return retval;
}

private Integer countCalls(List<fflib_MethodArgValues> methodArgs, fflib_MethodArgValues methodArg)
{
Integer count = 0;

for(fflib_MethodArgValues arg: methodArgs)
{
if( arg == methodArg) count++;
}

return count;
}

/*
* Method that validate the verification mode used in the verify.
* Not all the methods from the fflib_VerificationMode are implemented for the different classes that extends the fflib_MethodVerifier.
* The error is thrown at run time, so this method is called in the method that actually performs the verify.
* @param verificationMode The verification mode that have to been verified.
* @throws Exception with message for the fflib_VerificationMode not implemented.
*/
protected override void validateMode(fflib_VerificationMode verificationMode)
{
if(verificationMode.Method == fflib_VerificationMode.ModeName.CALLS)
{
throw new fflib_ApexMocks.ApexMocksException(
'The calls() method is available only in the InOrder Verification.');
}
}
}
5 changes: 5 additions & 0 deletions sfdx-source/apex-mocks/fflib_AnyOrder.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>52.0</apiVersion>
<status>Active</status>
</ApexClass>
Loading

0 comments on commit 573efa3

Please sign in to comment.