diff --git a/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy b/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy index 3e04af06..a735571d 100644 --- a/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy +++ b/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy @@ -18,11 +18,25 @@ class InterceptingGCL extends GroovyClassLoader { Map.Entry matchingMethod = helper.allowedMethodCallbacks.find { k, v -> k == signature } if (matchingMethod) { // a matching method was registered, replace script method execution call with the registered closure (mock) - metaClazz."$scriptMethod.name" = matchingMethod.value ?: {} + metaClazz."$scriptMethod.name" = matchingMethod.value ?: defaultClosure(matchingMethod.key.args) } } } + static Closure defaultClosure(Class[] args) { + int maxLength = 254 + if (args.length > maxLength) { + throw new IllegalArgumentException("Only $maxLength arguments allowed") + } + String argumentsString = args.inject("") { acc, value -> + return "${acc}${value.name} ${'a'*(acc.count(',') + 1)}," + } + String argumentsStringWithoutComma = argumentsString.size() > 0 ? + argumentsString.substring(0, argumentsString.length()-1) : argumentsString + String closureString = "{$argumentsStringWithoutComma -> }" + return (Closure)new GroovyShell().evaluate(closureString) + } + PipelineTestHelper helper Binding binding diff --git a/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestMockLocalFunction.groovy b/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestMockLocalFunction.groovy index f7c60376..60fa4844 100644 --- a/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestMockLocalFunction.groovy +++ b/src/test/groovy/com/lesfurets/jenkins/unit/declarative/TestMockLocalFunction.groovy @@ -1,10 +1,17 @@ package com.lesfurets.jenkins.unit.declarative +import static org.assertj.core.api.Assertions.assertThat + +import org.junit.runners.JUnit4 +import com.lesfurets.jenkins.unit.InterceptingGCL import org.junit.Before import org.junit.Test class TestMockLocalFunction extends DeclarativePipelineTest { + private static String SCRIPT_NO_PARAMS = "Mock_existing_function_Jenkinsfile" + private static String SCRIPT_PARAMS = SCRIPT_NO_PARAMS + "_params" + @Before @Override void setUp() throws Exception { @@ -14,13 +21,53 @@ class TestMockLocalFunction extends DeclarativePipelineTest { } @Test(expected=MissingMethodException.class) - void should_execute_with_errors() { - runScript("Mock_existing_function_Jenkinsfile") + void no_params_should_execute_with_errors() { + runScript(SCRIPT_NO_PARAMS) } @Test - void should_execute_without_errors() { + void no_params_should_execute_without_errors() { helper.registerAllowedMethod("runFunc") - runScript("Mock_existing_function_Jenkinsfile") + runScript(SCRIPT_NO_PARAMS) + } + + @Test(expected=MissingMethodException.class) + void params_should_execute_with_errors() { + runScript(SCRIPT_PARAMS) + } + + @Test + void params_should_execute_without_errors() { + helper.registerAllowedMethod("runFuncWithParam", [String]) + runScript(SCRIPT_PARAMS) + } + + @Test + void default_closure_empty() { + Class[] args = [] + default_closure_parameter_check(args) + } + + @Test + void default_closure_different_args() { + Class[] args = [Arrays.class, JUnit4.class, InterceptingGCL.class, String.class, Integer.class] + default_closure_parameter_check(args) + } + + @Test + void default_closure_max_args() { + Class[] args = (1..254).collect{ String.class } + default_closure_parameter_check(args) + } + + @Test(expected=IllegalArgumentException.class) + void default_closure_exceeded_args() { + Class[] args = (1..500).collect{ String.class } + default_closure_parameter_check(args) + } + + private static void default_closure_parameter_check(Class[] args) { + Closure closure = InterceptingGCL.defaultClosure(args) + assertThat(closure.getParameterTypes()).isEqualTo(args) } } diff --git a/src/test/jenkins/jenkinsfiles/Mock_existing_function_Jenkinsfile_params b/src/test/jenkins/jenkinsfiles/Mock_existing_function_Jenkinsfile_params new file mode 100644 index 00000000..6ab81ade --- /dev/null +++ b/src/test/jenkins/jenkinsfiles/Mock_existing_function_Jenkinsfile_params @@ -0,0 +1,16 @@ +pipeline { + agent { node { label 'test1' } } + stages { + stage('sdfsdf') { + steps { + githubNotify status: 'PENDING', context: 'Pipeline' + runFuncWithParam("one") + } + } + } +} + +def runFuncWithParam(String oneString) { + echo "inside runFuncWithParam" + doSomeStuffWithParam() +}