Add imports support in closures

This commit is contained in:
Dominik Przybysz 2015-12-22 15:24:06 +01:00
parent 261126d58b
commit 493bb8fd91
6 changed files with 237 additions and 171 deletions

View file

@ -1,17 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://touk.pl/mockserver/api/common" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema version="1.0" targetNamespace="http://touk.pl/mockserver/api/common" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="method"> <xs:simpleType name="method">
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:enumeration value="POST"/> <xs:enumeration value="POST"/>
<xs:enumeration value="GET"/> <xs:enumeration value="GET"/>
<xs:enumeration value="DELETE"/> <xs:enumeration value="DELETE"/>
<xs:enumeration value="PUT"/> <xs:enumeration value="PUT"/>
<xs:enumeration value="TRACE"/> <xs:enumeration value="TRACE"/>
<xs:enumeration value="HEAD"/> <xs:enumeration value="HEAD"/>
<xs:enumeration value="OPTIONS"/> <xs:enumeration value="OPTIONS"/>
<xs:enumeration value="PATCH"/> <xs:enumeration value="PATCH"/>
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
<xs:complexType name="importAlias">
<xs:attribute name="alias" type="xs:string"/>
<xs:attribute name="fullClassName" type="xs:string"/>
</xs:complexType>
</xs:schema> </xs:schema>

View file

@ -1,52 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://touk.pl/mockserver/api/request" xmlns:tns="http://touk.pl/mockserver/api/request" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:common="http://touk.pl/mockserver/api/common"> <xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://touk.pl/mockserver/api/request" xmlns:tns="http://touk.pl/mockserver/api/request" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:common="http://touk.pl/mockserver/api/common">
<xs:import namespace="http://touk.pl/mockserver/api/common" schemaLocation="common.xsd"/> <xs:import namespace="http://touk.pl/mockserver/api/common" schemaLocation="common.xsd"/>
<xs:element name="addMock" type="tns:AddMock"/> <xs:element name="addMock" type="tns:AddMock"/>
<xs:element name="peekMock" type="tns:PeekMock"/> <xs:element name="peekMock" type="tns:PeekMock"/>
<xs:element name="removeMock" type="tns:RemoveMock"/> <xs:element name="removeMock" type="tns:RemoveMock"/>
<xs:complexType name="AddMock"> <xs:complexType name="AddMock">
<xs:complexContent> <xs:complexContent>
<xs:extension base="tns:mockServerRequest"> <xs:extension base="tns:mockServerRequest">
<xs:sequence>
<xs:element name="path" type="xs:string"/>
<xs:element name="port" type="xs:int"/>
<xs:element name="predicate" type="xs:string" minOccurs="0"/>
<xs:element name="response" type="xs:string" minOccurs="0"/>
<xs:element name="soap" type="xs:boolean" minOccurs="0"/>
<xs:element name="statusCode" type="xs:int" minOccurs="0"/>
<xs:element name="method" type="common:method" minOccurs="0"/>
<xs:element name="responseHeaders" type="xs:string" minOccurs="0"/>
<xs:element name="schema" type="xs:string" minOccurs="0"/>
<xs:element name="imports" type="common:importAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockServerRequest" abstract="true">
<xs:sequence> <xs:sequence>
<xs:element name="path" type="xs:string"/> <xs:element name="name" type="xs:string"/>
<xs:element name="port" type="xs:int"/>
<xs:element name="predicate" type="xs:string" minOccurs="0"/>
<xs:element name="response" type="xs:string" minOccurs="0"/>
<xs:element name="soap" type="xs:boolean" minOccurs="0"/>
<xs:element name="statusCode" type="xs:int" minOccurs="0"/>
<xs:element name="method" type="common:method" minOccurs="0"/>
<xs:element name="responseHeaders" type="xs:string" minOccurs="0"/>
<xs:element name="schema" type="xs:string" minOccurs="0"/>
</xs:sequence> </xs:sequence>
</xs:extension> </xs:complexType>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockServerRequest" abstract="true"> <xs:complexType name="PeekMock">
<xs:sequence> <xs:complexContent>
<xs:element name="name" type="xs:string"/> <xs:extension base="tns:mockServerRequest"/>
</xs:sequence> </xs:complexContent>
</xs:complexType> </xs:complexType>
<xs:complexType name="PeekMock"> <xs:complexType name="RemoveMock">
<xs:complexContent> <xs:complexContent>
<xs:extension base="tns:mockServerRequest"/> <xs:extension base="tns:mockServerRequest">
</xs:complexContent> <xs:sequence>
</xs:complexType> <xs:element name="skipReport" type="xs:boolean" minOccurs="0"/>
</xs:sequence>
<xs:complexType name="RemoveMock"> </xs:extension>
<xs:complexContent> </xs:complexContent>
<xs:extension base="tns:mockServerRequest"> </xs:complexType>
<xs:sequence>
<xs:element name="skipReport" type="xs:boolean" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema> </xs:schema>

View file

@ -1,135 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://touk.pl/mockserver/api/response" xmlns:tns="http://touk.pl/mockserver/api/response" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:common="http://touk.pl/mockserver/api/common"> <xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://touk.pl/mockserver/api/response" xmlns:tns="http://touk.pl/mockserver/api/response" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:common="http://touk.pl/mockserver/api/common">
<xs:import namespace="http://touk.pl/mockserver/api/common" schemaLocation="common.xsd"/> <xs:import namespace="http://touk.pl/mockserver/api/common" schemaLocation="common.xsd"/>
<xs:element name="exceptionOccured" type="tns:exceptionOccured"/> <xs:element name="exceptionOccured" type="tns:exceptionOccured"/>
<xs:element name="mockAdded" type="tns:mockAdded"/> <xs:element name="mockAdded" type="tns:mockAdded"/>
<xs:element name="mockPeeked" type="tns:mockPeeked"/> <xs:element name="mockPeeked" type="tns:mockPeeked"/>
<xs:element name="mockRemoved" type="tns:mockRemoved"/> <xs:element name="mockRemoved" type="tns:mockRemoved"/>
<xs:element name="mocks" type="tns:mockListing"/> <xs:element name="mocks" type="tns:mockListing"/>
<xs:complexType name="exceptionOccured"> <xs:complexType name="exceptionOccured">
<xs:simpleContent> <xs:simpleContent>
<xs:extension base="xs:string"/> <xs:extension base="xs:string"/>
</xs:simpleContent> </xs:simpleContent>
</xs:complexType> </xs:complexType>
<xs:complexType name="mockAdded"> <xs:complexType name="mockAdded">
<xs:complexContent> <xs:complexContent>
<xs:extension base="tns:mockServerResponse"> <xs:extension base="tns:mockServerResponse">
<xs:sequence/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockServerResponse" abstract="true">
<xs:sequence/> <xs:sequence/>
</xs:extension> </xs:complexType>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockServerResponse" abstract="true"> <xs:complexType name="mockEventReport">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="mockEventReport">
<xs:sequence>
<xs:element name="request" type="tns:mockRequestReport"/>
<xs:element name="response" type="tns:mockResponseReport"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mockRequestReport">
<xs:sequence>
<xs:element name="text" type="xs:string" minOccurs="0"/>
<xs:element name="headers" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="header" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="queryParams" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="queryParam" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="path" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPart" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="parameter">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="mockResponseReport">
<xs:sequence>
<xs:element name="statusCode" type="xs:int"/>
<xs:element name="text" type="xs:string" minOccurs="0"/>
<xs:element name="headers" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="header" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mockListing">
<xs:complexContent>
<xs:extension base="tns:mockServerResponse">
<xs:sequence> <xs:sequence>
<xs:element name="mock" type="tns:mockReport" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="request" type="tns:mockRequestReport"/>
<xs:element name="response" type="tns:mockResponseReport"/>
</xs:sequence> </xs:sequence>
</xs:extension> </xs:complexType>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockReport"> <xs:complexType name="mockRequestReport">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="path" type="xs:string"/>
<xs:element name="port" type="xs:int"/>
<xs:element name="predicate" type="xs:string"/>
<xs:element name="response" type="xs:string"/>
<xs:element name="responseHeaders" type="xs:string"/>
<xs:element name="soap" type="xs:boolean"/>
<xs:element name="method" type="common:method"/>
<xs:element name="statusCode" type="xs:int"/>
<xs:element name="schema" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mockPeeked">
<xs:complexContent>
<xs:extension base="tns:mockServerResponse">
<xs:sequence> <xs:sequence>
<xs:element name="mockEvent" type="tns:mockEventReport" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="text" type="xs:string" minOccurs="0"/>
<xs:element name="headers" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="header" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="queryParams" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="queryParam" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="path" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="pathPart" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:extension> </xs:complexType>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockRemoved"> <xs:complexType name="parameter">
<xs:complexContent> <xs:simpleContent>
<xs:extension base="tns:mockServerResponse"> <xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="mockResponseReport">
<xs:sequence> <xs:sequence>
<xs:element name="mockEvent" type="tns:mockEventReport" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="statusCode" type="xs:int"/>
<xs:element name="text" type="xs:string" minOccurs="0"/>
<xs:element name="headers" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="header" type="tns:parameter" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:extension> </xs:complexType>
</xs:complexContent>
</xs:complexType> <xs:complexType name="mockListing">
<xs:complexContent>
<xs:extension base="tns:mockServerResponse">
<xs:sequence>
<xs:element name="mock" type="tns:mockReport" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockReport">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="path" type="xs:string"/>
<xs:element name="port" type="xs:int"/>
<xs:element name="predicate" type="xs:string"/>
<xs:element name="response" type="xs:string"/>
<xs:element name="responseHeaders" type="xs:string"/>
<xs:element name="soap" type="xs:boolean"/>
<xs:element name="method" type="common:method"/>
<xs:element name="statusCode" type="xs:int"/>
<xs:element name="schema" type="xs:string" minOccurs="0"/>
<xs:element name="imports" type="common:importAlias" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mockPeeked">
<xs:complexContent>
<xs:extension base="tns:mockServerResponse">
<xs:sequence>
<xs:element name="mockEvent" type="tns:mockEventReport" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="mockRemoved">
<xs:complexContent>
<xs:extension base="tns:mockServerResponse">
<xs:sequence>
<xs:element name="mockEvent" type="tns:mockEventReport" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema> </xs:schema>

View file

@ -1,17 +1,31 @@
package pl.touk.mockserver.tests package pl.touk.mockserver.tests
import groovy.util.slurpersupport.GPathResult 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.ContentType
import org.apache.http.entity.StringEntity import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils 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.common.Method
import pl.touk.mockserver.api.request.AddMock import pl.touk.mockserver.api.request.AddMock
import pl.touk.mockserver.api.response.MockEventReport import pl.touk.mockserver.api.response.MockEventReport
import pl.touk.mockserver.api.response.MockReport 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 pl.touk.mockserver.server.HttpMockServer
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification import spock.lang.Specification
@ -611,7 +625,7 @@ class MockServerIntegrationTest extends Specification {
restPostResponse.name == 'goodResponse-1' restPostResponse.name == 'goodResponse-1'
} }
def "should get list mocks"() { def "should get list of mocks"() {
given: given:
remoteMockServer.addMock(new AddMock( remoteMockServer.addMock(new AddMock(
name: 'testRest2', name: 'testRest2',
@ -648,7 +662,8 @@ class MockServerIntegrationTest extends Specification {
name: 'testRest', name: 'testRest',
path: 'testEndpoint', path: 'testEndpoint',
port: 9999, port: 9999,
schema: 'schema2.xsd' schema: 'schema2.xsd',
imports: [new ImportAlias(alias: 'aaa', fullClassName: 'bbb')]
)) ))
remoteMockServer.removeMock('testRest5') remoteMockServer.removeMock('testRest5')
when: 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[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[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]) 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<String, Object> props) { private static void assertMockReport(MockReport mockReport, Map<String, Object> props) {
@ -991,4 +1007,26 @@ class MockServerIntegrationTest extends Specification {
expect: expect:
remoteMockServer.removeMock('testSoap')?.size() == 2 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 -> "<goodResponseRest-${AAA.XMLNS_ATTRIBUTE}/>"}''',
soap: false,
imports: [new ImportAlias(alias: 'AAA', fullClassName: 'javax.xml.XMLConstants')]
))
when:
HttpPost restPost = new HttpPost('http://localhost:9999/testEndpoint')
restPost.entity = new StringEntity('<request/>', 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
}
} }

View file

@ -2,11 +2,21 @@ package pl.touk.mockserver.server
import com.sun.net.httpserver.HttpExchange import com.sun.net.httpserver.HttpExchange
import groovy.util.logging.Slf4j 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.AddMock
import pl.touk.mockserver.api.request.MockServerRequest import pl.touk.mockserver.api.request.MockServerRequest
import pl.touk.mockserver.api.request.PeekMock import pl.touk.mockserver.api.request.PeekMock
import pl.touk.mockserver.api.request.RemoveMock 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 javax.xml.bind.JAXBContext
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@ -65,7 +75,8 @@ class HttpMockServer {
soap: it.soap, soap: it.soap,
method: it.method, method: it.method,
statusCode: it.statusCode as int, 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) { private static Mock mockFromRequest(AddMock request) {
Mock mock = new Mock(request.name, request.path, request.port) Mock mock = new Mock(request.name, request.path, request.port)
mock.imports = request.imports?.collectEntries { [(it.alias): it.fullClassName] } ?: [:]
mock.predicate = request.predicate mock.predicate = request.predicate
mock.response = request.response mock.response = request.response
mock.soap = request.soap mock.soap = request.soap

View file

@ -3,6 +3,8 @@ package pl.touk.mockserver.server
import groovy.transform.EqualsAndHashCode import groovy.transform.EqualsAndHashCode
import groovy.transform.PackageScope import groovy.transform.PackageScope
import groovy.util.logging.Slf4j 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 pl.touk.mockserver.api.common.Method
import javax.xml.XMLConstants import javax.xml.XMLConstants
@ -31,6 +33,7 @@ class Mock implements Comparable<Mock> {
final List<MockEvent> history = new CopyOnWriteArrayList<>() final List<MockEvent> history = new CopyOnWriteArrayList<>()
String schema String schema
private Validator validator private Validator validator
Map<String, String> imports = [:]
Mock(String name, String path, int port) { Mock(String name, String path, int port) {
if (!(name)) { if (!(name)) {
@ -88,7 +91,13 @@ class Mock implements Comparable<Mock> {
if (predicate ==~ /(?m).*System\s*\.\s*exit\s*\(.*/) { if (predicate ==~ /(?m).*System\s*\.\s*exit\s*\(.*/) {
throw new RuntimeException('System.exit is forbidden') 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 return sh.evaluate(predicate) as Closure
} }