higher performance implementation for rewrite handler, test suite for rest functions, fast jersey junit tester, rewrite test suite
diff --git a/src/test/java/ClassLoaderTest.java b/src/test/java/ClassLoaderTest.java
new file mode 100644
index 0000000..4f9e455
--- /dev/null
+++ b/src/test/java/ClassLoaderTest.java
@@ -0,0 +1,41 @@
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.PluginHandler;
+import de.ids_mannheim.korap.interfaces.AuditingIface;
+import de.ids_mannheim.korap.interfaces.defaults.DefaultAuditing;
+import org.junit.Test;
+
+/**
+ * @author hanl
+ * @date 27/07/2015
+ */
+public class ClassLoaderTest {
+
+    @Test
+    public void testBeanConfigurationLoaderThrowsNoException() {
+        BeanConfiguration.loadClasspathContext("classpath-config.xml");
+        assert BeanConfiguration.getBeans() != null;
+    }
+
+    @Test
+    public void testDefaultCreationThrowsNoException() {
+        PluginHandler pl = new PluginHandler();
+        Object o = pl.getDefault(BeanConfiguration.KUSTVAKT_AUDITING);
+        assert o != null;
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testDefaultCreationThrowsException() {
+        BeanConfiguration.loadClasspathContext();
+        BeanConfiguration.getBeans().getAuthenticationManager();
+    }
+
+    @Test
+    public void testDefaultInterfaceMatchThrowsNoException() {
+        BeanConfiguration.loadClasspathContext();
+        AuditingIface iface = BeanConfiguration.getBeans()
+                .getAuditingProvider();
+        assert iface != null;
+        assert iface instanceof DefaultAuditing;
+    }
+
+}
diff --git a/src/test/java/FastJerseyTest.java b/src/test/java/FastJerseyTest.java
new file mode 100644
index 0000000..c51e62c
--- /dev/null
+++ b/src/test/java/FastJerseyTest.java
@@ -0,0 +1,116 @@
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.core.DefaultResourceConfig;
+import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.LowLevelAppDescriptor;
+import com.sun.jersey.test.framework.spi.container.TestContainer;
+import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
+import com.sun.jersey.test.framework.spi.container.grizzly.GrizzlyTestContainerFactory;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+
+/**
+ * @author hanl
+ * @date 29/07/2015
+ */
+public abstract class FastJerseyTest {
+
+    protected static String API_VERSION = "v0.1";
+
+    private static DefaultResourceConfig resourceConfig = new DefaultResourceConfig();
+
+    private static TestContainerFactory testContainerFactory;
+
+    private static TestContainer testContainer;
+
+    private static Client client;
+
+    public static void addClass(Class<?> resourceClass) {
+        resourceConfig.getClasses().add(resourceClass);
+    }
+
+    public static void addSingleton(Object resourceSingleton) {
+        resourceConfig.getSingletons().add(resourceSingleton);
+    }
+
+    public static <T> void addProviderForContext(Class<T> contextClass,
+            T contextObject) {
+        addSingleton(
+                new SingletonTypeInjectableProvider<Context, T>(contextClass,
+                        contextObject) {
+                });
+    }
+
+    public static void addRequestFilter(Object filter) {
+        resourceConfig.getContainerRequestFilters().add(filter);
+    }
+
+    public static void addResponseFilter(Object filter) {
+        resourceConfig.getContainerResponseFilters().add(filter);
+    }
+
+    public static void setTestContainerFactory(
+            TestContainerFactory newTestContainerFactory) {
+        testContainerFactory = newTestContainerFactory;
+    }
+
+    @BeforeClass
+    public static void cleanStaticVariables() {
+        resourceConfig = new DefaultResourceConfig();
+    }
+
+    public static void initServer() {
+        AppDescriptor ad = new LowLevelAppDescriptor.Builder(resourceConfig)
+                .build();
+        TestContainerFactory tcf = testContainerFactory;
+        if (tcf == null) {
+            tcf = new GrizzlyTestContainerFactory();
+        }
+        testContainer = tcf
+                .create(UriBuilder.fromUri("http://localhost/").port(9998)
+                        .build(), ad);
+        client = testContainer.getClient();
+        if (client == null) {
+            client = Client.create(ad.getClientConfig());
+        }
+    }
+
+    public static void startServer() {
+        if (testContainer != null) {
+            testContainer.start();
+        }
+    }
+
+    @AfterClass
+    public static void stopServer() {
+        testContainer.stop();
+        testContainer = null;
+        client = null;
+    }
+
+    public Client client() {
+        return client;
+    }
+
+    public URI getBaseUri() {
+        return testContainer.getBaseUri();
+    }
+
+    public WebResource resource() {
+        return client.resource(getBaseUri());
+    }
+
+    @Before
+    public void startServerBeforeFirstTestRun() {
+        if (testContainer == null) {
+            initServer();
+            startServer();
+        }
+    }
+}
diff --git a/src/test/java/KustvaktCoreRestTest.java b/src/test/java/KustvaktCoreRestTest.java
new file mode 100644
index 0000000..11a935a
--- /dev/null
+++ b/src/test/java/KustvaktCoreRestTest.java
@@ -0,0 +1,79 @@
+import com.sun.jersey.api.client.ClientResponse;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.query.serialize.CollectionQueryProcessor;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.service.LightService;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 26/06/2015
+ */
+public class KustvaktCoreRestTest extends FastJerseyTest {
+
+    @BeforeClass
+    public static void configure() {
+        BeanConfiguration.loadClasspathContext();
+        addClass(LightService.class);
+    }
+
+    @Test
+    public void testFieldsInSearch() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[base=Wort]").queryParam("ql", "poliqarp")
+                .get(ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testQuery() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "Sonne prox/unit=word/distance<=5 Erde")
+                .queryParam("ql", "CQL").get(ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    // in case no index is there, this will throw an error
+    @Ignore
+    @Test
+    public void testGetMatchInfoThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION)
+                .get(ClientResponse.class);
+    }
+
+    @Test
+    public void testGetStatsThrowsNoException() {
+        CollectionQueryProcessor pr = new CollectionQueryProcessor();
+        pr.process("corpusID=WPD & textClass=Sport");
+        Map map = new LinkedHashMap();
+        map.put("collection", pr.getRequestMap());
+        ClientResponse response = resource().path(API_VERSION).path("stats")
+                .post(ClientResponse.class, JsonUtils.toJSON(map));
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testBuildQueryThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[base=Haus & surface=Hauses]")
+                .queryParam("ql", "poliqarp").queryParam("cutOff", "true")
+                .queryParam("page", "1").method("TRACE", ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testQueryByNameThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION).path("corpus")
+                .path("WPD").path("search")
+                .queryParam("q", "[base=Haus & surface=Hauses]")
+                .queryParam("ql", "poliqarp").queryParam("cutOff", "true")
+                .queryParam("page", "1").get(ClientResponse.class);
+        System.out.println("RESPONSE " + response);
+    }
+
+}
diff --git a/src/test/java/RewriteTest.java b/src/test/java/RewriteTest.java
index 92e61fd..f06390e 100644
--- a/src/test/java/RewriteTest.java
+++ b/src/test/java/RewriteTest.java
@@ -1,8 +1,11 @@
+import com.fasterxml.jackson.databind.JsonNode;
 import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resource.LayerMapper;
 import de.ids_mannheim.korap.resource.RewriteProcessor;
-import de.ids_mannheim.korap.utils.CollectionQueryBuilder3;
+import de.ids_mannheim.korap.resource.rewrite.*;
+import de.ids_mannheim.korap.utils.JsonUtils;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -10,6 +13,7 @@
  * @author hanl
  * @date 18/06/2015
  */
+//todo: refactor and structure tests
 public class RewriteTest {
 
     private static String simple_add_query = "[pos=ADJA]";
@@ -18,42 +22,174 @@
     private static String complex_rewrite_query2 = "[orth=laufe/i & base!=Lauf]";
     private static String complex_rewrite_query3 = "[(base=laufen | base=gehen) & tt/pos=VVFIN]";
 
-    public RewriteTest() {
-
-    }
+    private static KustvaktConfiguration config;
 
     @BeforeClass
     public static void init() {
-        BeanConfiguration.loadFileContext(
-                "/Users/hanl/Projects/KorAP-project/KorAP-modules/Kustvakt-core/src/main/resources/default-config.xml");
+        BeanConfiguration.loadClasspathContext();
+        config = BeanConfiguration.getBeans().getConfiguration();
     }
 
     @Test
-    public void testQuery() {
+    public void testSimpleFoundryAddThrowsNoError() {
+        RewriteProcessor processor = new RewriteProcessor(config);
         QuerySerializer s = new QuerySerializer();
         s.setQuery(simple_add_query, "poliqarp");
-        System.out.println("query " + s.toJSON());
-
-        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
-        b.add("textClass=politik & corpusID=WPD");
-        System.out.println("collection query " + b.toJSON());
+        String result = processor.process(s.toJSON());
+        JsonNode node = JsonUtils.readTree(result);
+        assert !node.at("/query/wrap/foundry").isMissingNode();
     }
 
     @Test
-    public void testLayerMapper() {
-        LayerMapper m = new LayerMapper();
-        System.out.println("foundry " + m.findFoundry("lemma"));
-        System.out.println("foundry " + m.findFoundry("surface"));
-        System.out.println("foundry " + m.findFoundry("pos"));
+    public void testDefaultLayerMapperThrowsNoException() {
+        LayerMapper m = new LayerMapper(config);
+
+        assert m.findFoundry("lemma").equals(config.getDefault_lemma());
+        assert m.findFoundry("pos").equals(config.getDefault_pos());
+        assert m.findFoundry("surface").equals(config.getDefault_surface());
+        assert m.findFoundry("d").equals(config.getDefault_dep());
+        assert m.findFoundry("c").equals(config.getDefault_const());
     }
 
     @Test
-    public void testRewrite() {
-        RewriteProcessor processor = new RewriteProcessor();
-
+    public void testFoundryInjectPosNoErrors() {
         QuerySerializer s = new QuerySerializer();
-        s.setQuery(complex_rewrite_query3, "poliqarp");
-        System.out.println("query " + s.toJSON());
-        System.out.println("finished node " + processor.process(s.toJSON()));
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[pos=ADJA]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+        assert !node.at("/query/wrap/foundry").isMissingNode();
+        assert !node.at("/query/wrap/rewrites").isMissingNode();
+        assert node.at("/query/wrap/rewrites/0/@type").asText()
+                .equals("koral:rewrite");
     }
+
+    @Test
+    public void testFoundryInjectJoinedQueryNoErrors() {
+        QuerySerializer s = new QuerySerializer();
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[orth=laufe/i & base!=Lauf]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+        assert node.at("/query/wrap/@type").asText().equals("koral:termGroup");
+        assert !node.at("/query/wrap/operands/0/foundry").isMissingNode();
+        assert !node.at("/query/wrap/operands/0/rewrites").isMissingNode();
+        assert !node.at("/query/wrap/operands/1/foundry").isMissingNode();
+        assert !node.at("/query/wrap/operands/1/rewrites").isMissingNode();
+    }
+
+    @Test
+    public void testFoundryInjectGroupedQueryNoErrors() {
+        QuerySerializer s = new QuerySerializer();
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[(base=laufen | base=gehen) & tt/pos=VVFIN]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+
+        assert node.at("/query/wrap/@type").asText().equals("koral:termGroup");
+        assert !node.at("/query/wrap/operands/0/operands/0/foundry")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/0/rewrites")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/1/foundry")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/1/rewrites")
+                .isMissingNode();
+
+        assert !node.at("/query/wrap/operands/1/foundry").isMissingNode();
+        assert node.at("/query/wrap/operands/1/rewrites").isMissingNode();
+    }
+
+    @Test
+    public void testCollectionNodeRemoveCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("textClass=politik & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/operands").size() == 1;
+    }
+
+    @Test
+    public void testCollectionNodeRemoveAllCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("corpusID=BRZ13 & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/operands").size() == 0;
+    }
+
+    @Test
+    public void testCollectionNodeRemoveGroupedCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & textClass=Wissenschaft) & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+
+        assert node.at("/collection/operands/0/@type").asText()
+                .equals("koral:docGroup");
+        assert node.at("/collection/operands/0/operands/0/key").asText()
+                .equals("textClass");
+    }
+
+    //fixme: will probably fail when one doc groups are being refactored
+    @Test
+    public void testCollectionCleanEmptyDocGroupNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft & textClass=Sport");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:docGroup");
+        assert node.at("/collection/operands").size() == 2;
+        assert node.at("/collection/operands/0/key").asText()
+                .equals("textClass");
+        assert node.at("/collection/operands/1/key").asText()
+                .equals("textClass");
+    }
+
+    @Test
+    public void testCollectionCleanMoveOneDocFromGroupUpNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("(corpusID=BRZ13 & textClass=Wissenschaft)");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:doc");
+    }
+
+    @Test
+    public void testCollectionCleanEmptyGroupAndMoveOneDocFromGroupUpNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:doc");
+        assert node.at("/collection/key").asText().equals("textClass");
+    }
+
 }