From 493bb8fd912dcff166ac1d9a060e38c1cb9e7862 Mon Sep 17 00:00:00 2001 From: Dominik Przybysz Date: Tue, 22 Dec 2015 15:24:06 +0100 Subject: [PATCH] Add imports support in closures --- .../xsd/pl/touk/mockserver/api/common.xsd | 29 ++- .../xsd/pl/touk/mockserver/api/request.xsd | 79 +++--- .../xsd/pl/touk/mockserver/api/response.xsd | 227 +++++++++--------- .../tests/MockServerIntegrationTest.groovy | 46 +++- .../mockserver/server/HttpMockServer.groovy | 16 +- .../pl/touk/mockserver/server/Mock.groovy | 11 +- 6 files changed, 237 insertions(+), 171 deletions(-) diff --git a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/common.xsd b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/common.xsd index a48f724..ac21246 100644 --- a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/common.xsd +++ b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/common.xsd @@ -1,17 +1,22 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/request.xsd b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/request.xsd index 10c7190..809cb44 100644 --- a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/request.xsd +++ b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/request.xsd @@ -1,52 +1,53 @@ - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + - - - + - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/response.xsd b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/response.xsd index 9e630dc..152a293 100644 --- a/mockserver-api/src/main/xsd/pl/touk/mockserver/api/response.xsd +++ b/mockserver-api/src/main/xsd/pl/touk/mockserver/api/response.xsd @@ -1,135 +1,136 @@ - + - + - + - + - + - + - - - - - + + + + + - - - + + + + + + + + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + - - - + - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + - - - + - - - + + + + + + + + + - + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy index fa61e4a..1412de1 100644 --- a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy +++ b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy @@ -1,17 +1,31 @@ package pl.touk.mockserver.tests import groovy.util.slurpersupport.GPathResult -import org.apache.http.client.methods.* +import org.apache.http.client.methods.CloseableHttpResponse +import org.apache.http.client.methods.HttpDelete +import org.apache.http.client.methods.HttpGet +import org.apache.http.client.methods.HttpHead +import org.apache.http.client.methods.HttpOptions +import org.apache.http.client.methods.HttpPatch +import org.apache.http.client.methods.HttpPost +import org.apache.http.client.methods.HttpPut +import org.apache.http.client.methods.HttpTrace import org.apache.http.entity.ContentType import org.apache.http.entity.StringEntity import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients import org.apache.http.util.EntityUtils +import pl.touk.mockserver.api.common.ImportAlias import pl.touk.mockserver.api.common.Method import pl.touk.mockserver.api.request.AddMock import pl.touk.mockserver.api.response.MockEventReport import pl.touk.mockserver.api.response.MockReport -import pl.touk.mockserver.client.* +import pl.touk.mockserver.client.InvalidMockDefinition +import pl.touk.mockserver.client.InvalidMockRequestSchema +import pl.touk.mockserver.client.MockAlreadyExists +import pl.touk.mockserver.client.MockDoesNotExist +import pl.touk.mockserver.client.RemoteMockServer +import pl.touk.mockserver.client.Util import pl.touk.mockserver.server.HttpMockServer import spock.lang.Shared import spock.lang.Specification @@ -611,7 +625,7 @@ class MockServerIntegrationTest extends Specification { restPostResponse.name == 'goodResponse-1' } - def "should get list mocks"() { + def "should get list of mocks"() { given: remoteMockServer.addMock(new AddMock( name: 'testRest2', @@ -648,7 +662,8 @@ class MockServerIntegrationTest extends Specification { name: 'testRest', path: 'testEndpoint', port: 9999, - schema: 'schema2.xsd' + schema: 'schema2.xsd', + imports: [new ImportAlias(alias: 'aaa', fullClassName: 'bbb')] )) remoteMockServer.removeMock('testRest5') when: @@ -660,6 +675,7 @@ class MockServerIntegrationTest extends Specification { assertMockReport(mockReport[2], [name: 'testRest3', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: false, statusCode: 200, method: Method.POST]) assertMockReport(mockReport[3], [name: 'testRest4', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: true, statusCode: 204, method: Method.PUT]) assertMockReport(mockReport[4], [name: 'testRest6', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: false, statusCode: 200, method: Method.POST]) + mockReport[0].imports.find { it.alias == 'aaa' }?.fullClassName == 'bbb' } private static void assertMockReport(MockReport mockReport, Map props) { @@ -991,4 +1007,26 @@ class MockServerIntegrationTest extends Specification { expect: remoteMockServer.removeMock('testSoap')?.size() == 2 } + + def "should add mock with alias"() { + expect: + remoteMockServer.addMock(new AddMock( + name: 'testRest', + path: 'testEndpoint', + port: 9999, + predicate: '''{req -> req.xml.name() == 'request'}''', + response: '''{req -> ""}''', + soap: false, + imports: [new ImportAlias(alias: 'AAA', fullClassName: 'javax.xml.XMLConstants')] + )) + when: + HttpPost restPost = new HttpPost('http://localhost:9999/testEndpoint') + restPost.entity = new StringEntity('', ContentType.create("text/xml", "UTF-8")) + CloseableHttpResponse response = client.execute(restPost) + then: + GPathResult restPostResponse = Util.extractXmlResponse(response) + restPostResponse.name() == 'goodResponseRest-xmlns' + expect: + remoteMockServer.removeMock('testRest')?.size() == 1 + } } diff --git a/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy b/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy index 8eaab6d..c25b990 100644 --- a/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy +++ b/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy @@ -2,11 +2,21 @@ package pl.touk.mockserver.server import com.sun.net.httpserver.HttpExchange import groovy.util.logging.Slf4j +import pl.touk.mockserver.api.common.ImportAlias import pl.touk.mockserver.api.request.AddMock import pl.touk.mockserver.api.request.MockServerRequest import pl.touk.mockserver.api.request.PeekMock import pl.touk.mockserver.api.request.RemoveMock -import pl.touk.mockserver.api.response.* +import pl.touk.mockserver.api.response.ExceptionOccured +import pl.touk.mockserver.api.response.MockAdded +import pl.touk.mockserver.api.response.MockEventReport +import pl.touk.mockserver.api.response.MockPeeked +import pl.touk.mockserver.api.response.MockRemoved +import pl.touk.mockserver.api.response.MockReport +import pl.touk.mockserver.api.response.MockRequestReport +import pl.touk.mockserver.api.response.MockResponseReport +import pl.touk.mockserver.api.response.Mocks +import pl.touk.mockserver.api.response.Parameter import javax.xml.bind.JAXBContext import java.util.concurrent.ConcurrentHashMap @@ -65,7 +75,8 @@ class HttpMockServer { soap: it.soap, method: it.method, statusCode: it.statusCode as int, - schema: it.schema + schema: it.schema, + imports: it.imports.collect { new ImportAlias(alias: it.key, fullClassName: it.value) } ) } ) @@ -90,6 +101,7 @@ class HttpMockServer { private static Mock mockFromRequest(AddMock request) { Mock mock = new Mock(request.name, request.path, request.port) + mock.imports = request.imports?.collectEntries { [(it.alias): it.fullClassName] } ?: [:] mock.predicate = request.predicate mock.response = request.response mock.soap = request.soap diff --git a/mockserver/src/main/groovy/pl/touk/mockserver/server/Mock.groovy b/mockserver/src/main/groovy/pl/touk/mockserver/server/Mock.groovy index 15b538f..6511078 100644 --- a/mockserver/src/main/groovy/pl/touk/mockserver/server/Mock.groovy +++ b/mockserver/src/main/groovy/pl/touk/mockserver/server/Mock.groovy @@ -3,6 +3,8 @@ package pl.touk.mockserver.server import groovy.transform.EqualsAndHashCode import groovy.transform.PackageScope import groovy.util.logging.Slf4j +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.control.customizers.ImportCustomizer import pl.touk.mockserver.api.common.Method import javax.xml.XMLConstants @@ -31,6 +33,7 @@ class Mock implements Comparable { final List history = new CopyOnWriteArrayList<>() String schema private Validator validator + Map imports = [:] Mock(String name, String path, int port) { if (!(name)) { @@ -88,7 +91,13 @@ class Mock implements Comparable { if (predicate ==~ /(?m).*System\s*\.\s*exit\s*\(.*/) { throw new RuntimeException('System.exit is forbidden') } - GroovyShell sh = new GroovyShell(this.class.classLoader); + CompilerConfiguration compilerConfiguration = new CompilerConfiguration() + ImportCustomizer customizer = new ImportCustomizer() + imports.each { + customizer.addImport(it.key, it.value) + } + compilerConfiguration.addCompilationCustomizers(customizer) + GroovyShell sh = new GroovyShell(this.class.classLoader, compilerConfiguration); return sh.evaluate(predicate) as Closure }