aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test
Publish
Diffstat (limited to 'container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test')
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml4
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml41
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java59
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml17
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml36
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java51
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml20
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml29
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java68
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml7
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml17
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java51
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml45
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml55
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java50
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java74
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml28
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml96
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java90
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml22
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml73
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java88
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml31
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml43
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java44
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml37
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml45
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java44
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml36
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml43
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java44
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml7
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml17
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java43
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml5
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml65
-rw-r--r--container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java140
37 files changed, 1665 insertions, 0 deletions
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml
new file mode 100644
index 00000000000..4a5b6b3a1dd
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySource.xml
@@ -0,0 +1,4 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="AnySource" source="source3 *">
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml
new file mode 100644
index 00000000000..40cc6b6935e
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceResult.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0">
+
+ <hit relevance="1.0" source="source3">
+ <id>source3-1</id>
+ </hit>
+
+ <hit relevance="1.0" source="source1">
+ <id>source1-1</id>
+ </hit>
+
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+
+ <hit relevance="0.5" source="source3">
+ <id>source3-2</id>
+ </hit>
+
+ <hit relevance="0.5" source="source1">
+ <id>source1-2</id>
+ </hit>
+
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source3">
+ <id>source3-3</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source1">
+ <id>source1-3</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java
new file mode 100644
index 00000000000..dc20e5483ca
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/AnySourceTestCase.java
@@ -0,0 +1,59 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.result.HitGroup;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author bratseth
+ */
+public class AnySourceTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("AnySource.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",3));
+ result.hits().add(createHits("source3",3));
+
+ // Resolve (noop here)
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check execution:
+ // all three sources, ordered by relevance, source 3 first in each relevance group
+ HitGroup hits=result.hits();
+ assertEquals(9,hits.size());
+ assertEquals("source3-1",hits.get(0).getId().stringValue());
+ assertEquals("source1-1",hits.get(1).getId().stringValue());
+ assertEquals("source2-1",hits.get(2).getId().stringValue());
+ assertEquals("source3-2",hits.get(3).getId().stringValue());
+ assertEquals("source1-2",hits.get(4).getId().stringValue());
+ assertEquals("source2-2",hits.get(5).getId().stringValue());
+ assertEquals("source3-3",hits.get(6).getId().stringValue());
+ assertEquals("source1-3",hits.get(7).getId().stringValue());
+ assertEquals("source2-3",hits.get(8).getId().stringValue());
+
+ // Check rendering
+ assertRendered(result,"AnySourceResult.xml");
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml
new file mode 100644
index 00000000000..e0306872149
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderers.xml
@@ -0,0 +1,17 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="ChoiceOfRenderers" source="source1 source2">
+
+ <choice>
+ <renderer name="sectionLook1"/>
+ <renderer name="sectionLook2"/>
+ </choice>
+ <choice>
+ <renderer name="source1Look1" for="source1"/>
+ <renderer name="source1Look2" for="source1"/>
+ <renderer name="source1Look3" for="source1">
+ <parameter name="color">#ff00ff</parameter>
+ <parameter name="blink">true</parameter>
+ </renderer>
+ </choice>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml
new file mode 100644
index 00000000000..47ed1bd2f12
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersResult.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0">
+
+ <renderer name="sectionLook2"/>
+
+ <renderer for="source1" name="source1Look3">
+ <parameter name="color">#ff00ff</parameter>
+ <parameter name="blink">true</parameter>
+ </renderer>
+
+ <hit relevance="1.0" source="source1">
+ <id>source1-1</id>
+ </hit>
+
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+
+ <hit relevance="0.5" source="source1">
+ <id>source1-2</id>
+ </hit>
+
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source1">
+ <id>source1-3</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java
new file mode 100644
index 00000000000..58d05971805
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfRenderersTestCase.java
@@ -0,0 +1,51 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.PageTemplate;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.pagetemplates.model.Renderer;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class ChoiceOfRenderersTestCase extends ExecutionAbstractTestCase {
+
+ //This test is order dependent. Fix this!!
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("ChoiceOfRenderers.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",3));
+ result.hits().add(createHits("source3",3));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+ assertEquals(1,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Renderer.class).get(0)));
+ assertEquals(2,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Renderer.class).get(1)));
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ assertEquals(6,result.getConcreteHitCount());
+ assertEquals(6,result.getHitCount());
+
+ // Check rendering
+ assertRendered(result,"ChoiceOfRenderersResult.xml");
+ }
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml
new file mode 100644
index 00000000000..f7323ba094d
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsections.xml
@@ -0,0 +1,20 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="ChoiceOfSubsections">
+ <choice method="method1">
+ <alternative>
+ <section source="source0"/>
+ </alternative>
+ <alternative>
+ <section source="source1"/>
+ </alternative>
+ <alternative>
+ <section source="source2"/>
+ <section>
+ <choice method="method2">
+ <source name="source3"/>
+ <source name="source4"/>
+ </choice>
+ </section>
+ </alternative>
+ </choice>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml
new file mode 100644
index 00000000000..b1d29995312
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsResult.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0">
+
+ <section>
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+ </section>
+
+ <section>
+ <hit relevance="1.0" source="source4">
+ <id>source4-1</id>
+ </hit>
+ <hit relevance="0.5" source="source4">
+ <id>source4-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source4">
+ <id>source4-3</id>
+ </hit>
+ </section>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java
new file mode 100644
index 00000000000..3d92a721f0d
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfSubsectionsTestCase.java
@@ -0,0 +1,68 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.result.HitGroup;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class ChoiceOfSubsectionsTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("ChoiceOfSubsections.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",3));
+ result.hits().add(createHits("source3",3));
+ result.hits().add(createHits("source4",3));
+
+ new Organizer().organize(page,new DeterministicResolverAssertingMethod().resolve(page,query,result),result);
+
+ // Check execution:
+ // Two subsections with one source each
+ assertEquals(2,result.hits().size());
+ HitGroup section1=(HitGroup)result.hits().get(0);
+ HitGroup section2=(HitGroup)result.hits().get(1);
+ assertEqualHitGroups(createHits("source2",3),section1);
+ assertEqualHitGroups(createHits("source4",3),section2);
+
+ // Check rendering
+ assertRendered(result,"ChoiceOfSubsectionsResult.xml");
+ }
+
+ /** Same as deterministic resolver, but asserts that it received the correct method names for each choice */
+ private static class DeterministicResolverAssertingMethod extends DeterministicResolver {
+
+ private int invocationNumber=0;
+
+ /** Chooses the last alternative of any choice */
+ @Override
+ public void resolve(Choice choice, Query query, Result result, Resolution resolution) {
+ invocationNumber++;
+ if (invocationNumber==2)
+ assertEquals("method1",choice.getMethod());
+ else if (invocationNumber==3)
+ assertEquals("method2",choice.getMethod());
+ else if (invocationNumber>3)
+ throw new IllegalStateException("Unexpected number of resolver invocations");
+
+ super.resolve(choice,query,result,resolution);
+ }
+
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml
new file mode 100644
index 00000000000..c6a0af9ddd2
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSources.xml
@@ -0,0 +1,7 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="ChoiceOfTwoSources">
+ <choice>
+ <source name="source1"/>
+ <source name="source2"/>
+ </choice>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml
new file mode 100644
index 00000000000..35d913fd9fa
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesResult.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0">
+
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java
new file mode 100644
index 00000000000..facffb50649
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoiceOfTwoSourcesTestCase.java
@@ -0,0 +1,51 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.PageTemplate;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.pagetemplates.model.Source;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class ChoiceOfTwoSourcesTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("ChoiceOfTwoSources.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",3));
+ result.hits().add(createHits("source3",3));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+ assertEquals(1,resolution.getResolution((Choice)((PageTemplate)page.get(0).get(0)).getSection().elements(Source.class).get(0)));
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check execution:
+ // No subsections: Last choice (source2) used
+ assertEqualHitGroups(createHits("source2",3),result.hits());
+
+ // Check rendering
+ assertRendered(result,"ChoiceOfTwoSourcesResult.xml");
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml
new file mode 100644
index 00000000000..e8d1736f46c
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Choices.xml
@@ -0,0 +1,45 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="Choices">
+ <choice>
+
+ <alternative>
+ <section layout="row">
+ <section id="realtime">
+ <choice>
+ <source name="news"/>
+ <source name="blog"/>
+ </choice>
+ </section>
+ <section source="images" max="2" id="multimedia"/>
+ <section source="web" id="web"/>
+ </section>
+ </alternative>
+
+ <alternative>
+ <section source="*" id="blended"/>
+ </alternative>
+
+ <alternative>
+ <section layout="row" description="row 1">
+ <section id="box1"><placeholder id="box1source"/></section>
+ <section id="box2"><placeholder id="box2source"/></section>
+ </section>
+ <section layout="row" description="row 2">
+ <section id="box3"><placeholder id="box3source"/></section>
+ <section id="box4"><placeholder id="box4source"/></section>
+ </section>
+
+ <choice method="myMethod">
+ <map to="box1source box2source box3source box4source">
+ <source name="news"/>
+ <source name="web"/>
+ <source name="blog"/>
+ <source name="images"/>
+ </map>
+ </choice>
+
+ </alternative>
+
+ </choice>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml
new file mode 100644
index 00000000000..ab995365f22
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesResult.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0">
+
+ <section layout="row">
+ <section id="section:box1">
+ <hit relevance="1.0" source="news">
+ <id>news-1</id>
+ </hit>
+ <hit relevance="0.5" source="news">
+ <id>news-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="news">
+ <id>news-3</id>
+ </hit>
+ </section>
+ <section id="section:box2">
+ <hit relevance="1.0" source="web">
+ <id>web-1</id>
+ </hit>
+ <hit relevance="0.5" source="web">
+ <id>web-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="web">
+ <id>web-3</id>
+ </hit>
+ </section>
+ </section>
+
+ <section layout="row">
+ <section id="section:box3">
+ <hit relevance="1.0" source="blog">
+ <id>blog-1</id>
+ </hit>
+ <hit relevance="0.5" source="blog">
+ <id>blog-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="blog">
+ <id>blog-3</id>
+ </hit>
+ </section>
+ <section id="section:box4">
+ <hit relevance="1.0" source="images">
+ <id>images-1</id>
+ </hit>
+ <hit relevance="0.5" source="images">
+ <id>images-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="images">
+ <id>images-3</id>
+ </hit>
+ </section>
+ </section>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java
new file mode 100644
index 00000000000..a646823c8cb
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ChoicesTestCase.java
@@ -0,0 +1,50 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.pagetemplates.model.PageElement;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class ChoicesTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template (second alternative will be chosen)
+ List<PageElement> pages=new ArrayList<>();
+ pages.add(importPage("AnySource.xml"));
+ pages.add(importPage("Choices.xml"));
+ Choice page=Choice.createSingletons(pages);
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("news",3));
+ result.hits().add(createHits("web",3));
+ result.hits().add(createHits("blog",3));
+ result.hits().add(createHits("images",3));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check rendering
+ assertRendered(result,"ChoicesResult.xml");
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java
new file mode 100644
index 00000000000..544366758f3
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java
@@ -0,0 +1,74 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.io.IOUtils;
+import com.yahoo.prelude.templates.TiledTemplateSet;
+import com.yahoo.prelude.templates.UserTemplate;
+import com.yahoo.prelude.templates.test.TilingTestCase;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.PageTemplate;
+import com.yahoo.search.pagetemplates.config.PageTemplateXMLReader;
+import com.yahoo.search.result.Hit;
+import com.yahoo.search.result.HitGroup;
+
+import java.io.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author bratseth
+ */
+public class ExecutionAbstractTestCase {
+
+ private static final String root="src/test/java/com/yahoo/search/pagetemplates/engine/test/";
+
+ protected PageTemplate importPage(String name) {
+ PageTemplate template=new PageTemplateXMLReader().readFile(root + name);
+ assertNotNull("Could look up page template '" + name + "'",template);
+ return template;
+ }
+
+ protected void assertEqualHitGroups(HitGroup expected,HitGroup actual) {
+ assertEquals(expected.size(),actual.size());
+ int i=0;
+ for (Hit expectedHit : expected.asList()) {
+ Hit actualHit=actual.get(i++);
+ assertEquals(expectedHit.getId(),actualHit.getId());
+ assertEquals(expectedHit.getSource(),actualHit.getSource());
+ }
+ }
+
+ protected HitGroup createHits(String sourceName,int hitCount) {
+ HitGroup source=new HitGroup("source:" + sourceName);
+ for (int i=1; i<=hitCount; i++) {
+ Hit hit=new Hit(sourceName + "-" + i,1/(double)i);
+ hit.setSource(sourceName);
+ source.add(hit);
+ }
+ return source;
+ }
+
+ protected void assertRendered(Result result,String resultFileName) {
+ assertRendered(result,resultFileName,false);
+ }
+
+ protected void assertRendered(Result result,String resultFileName, UserTemplate<?> template) {
+ assertRendered(result,resultFileName,template,false);
+ }
+
+ protected void assertRendered(Result result,String resultFileName,boolean print) {
+ assertRendered(result,resultFileName,new TiledTemplateSet(),print);
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void assertRendered(Result result,String resultFileName,UserTemplate<?> template, boolean print) {
+ result.getTemplating().setTemplates(template);
+ try {
+ TilingTestCase.assertRendered(IOUtils.readFile(new File(root + resultFileName)), result);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml
new file mode 100644
index 00000000000..2bc75fba5f4
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSections.xml
@@ -0,0 +1,28 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="MapSectionsToSections" layout="column" description="Contains 4 boxes, to which 4 sections are mapped">
+
+ <section layout="row" description="row 1">
+ <placeholder id="box1holder"/>
+ <placeholder id="box2holder"/>
+ </section>
+ <section layout="row" description="row 2">
+ <placeholder id="box3holder"/>
+ <placeholder id="box4holder"/>
+ </section>
+
+ <choice method="myMethod">
+ <map to="box1holder box2holder box3holder box4holder">
+ <section id="box1" source="source1"/>
+ <section id="box2" source="source2"/>
+ <item>
+ <section id="box3" source="source3"/>
+ <section id="box5" source="source5"/>
+ </item>
+ <section id="box4" source="source4"/>
+ </map>
+ </choice>
+
+ <choice> <!-- Empty choices should have no effect -->
+ </choice>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml
new file mode 100644
index 00000000000..3a163e5f804
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsResult.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0" layout="column">
+
+ <section layout="row">
+ <section id="section:box1">
+ <hit relevance="1.0" source="source1">
+ <id>source1-1</id>
+ </hit>
+ <hit relevance="0.5" source="source1">
+ <id>source1-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source1">
+ <id>source1-3</id>
+ </hit>
+ </section>
+ <section id="section:box2">
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+ <hit relevance="0.25" source="source2">
+ <id>source2-4</id>
+ </hit>
+ </section>
+ </section>
+
+ <section layout="row">
+ <section id="section:box3">
+ <hit relevance="1.0" source="source3">
+ <id>source3-1</id>
+ </hit>
+ <hit relevance="0.5" source="source3">
+ <id>source3-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source3">
+ <id>source3-3</id>
+ </hit>
+ <hit relevance="0.25" source="source3">
+ <id>source3-4</id>
+ </hit>
+ <hit relevance="0.2" source="source3">
+ <id>source3-5</id>
+ </hit>
+ </section>
+ <section id="section:box5">
+ <hit relevance="1.0" source="source5">
+ <id>source5-1</id>
+ </hit>
+ <hit relevance="0.5" source="source5">
+ <id>source5-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source5">
+ <id>source5-3</id>
+ </hit>
+ <hit relevance="0.25" source="source5">
+ <id>source5-4</id>
+ </hit>
+ <hit relevance="0.2" source="source5">
+ <id>source5-5</id>
+ </hit>
+ <hit relevance="0.1666666666666667" source="source5">
+ <id>source5-6</id>
+ </hit>
+ <hit relevance="0.1428571428571428" source="source5">
+ <id>source5-7</id>
+ </hit>
+ </section>
+ <section id="section:box4">
+ <hit relevance="1.0" source="source4">
+ <id>source4-1</id>
+ </hit>
+ <hit relevance="0.5" source="source4">
+ <id>source4-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source4">
+ <id>source4-3</id>
+ </hit>
+ <hit relevance="0.25" source="source4">
+ <id>source4-4</id>
+ </hit>
+ <hit relevance="0.2" source="source4">
+ <id>source4-5</id>
+ </hit>
+ <hit relevance="0.1666666666666667" source="source4">
+ <id>source4-6</id>
+ </hit>
+ </section>
+ </section>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java
new file mode 100644
index 00000000000..54fc342aa22
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSectionsToSectionsTestCase.java
@@ -0,0 +1,90 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.PageTemplate;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.pagetemplates.model.MapChoice;
+import com.yahoo.search.pagetemplates.model.PageElement;
+import com.yahoo.search.pagetemplates.model.Section;
+import com.yahoo.search.result.HitGroup;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class MapSectionsToSectionsTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("MapSectionsToSections.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",4));
+ result.hits().add(createHits("source3",5));
+ result.hits().add(createHits("source4",6));
+ result.hits().add(createHits("source5",7));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolverAssertingMethod();
+ Resolution resolution=resolver.resolve(page,query,result);
+ Map<String, List<PageElement>> mapping=
+ resolution.getResolution((MapChoice)((PageTemplate)page.get(0).get(0)).getSection().elements().get(2));
+ assertNotNull(mapping);
+ assertEquals("box1",((Section)mapping.get("box1holder").get(0)).getId());
+ assertEquals("box2",((Section)mapping.get("box2holder").get(0)).getId());
+ assertEquals("box3",((Section)mapping.get("box3holder").get(0)).getId());
+ assertEquals("box4",((Section)mapping.get("box4holder").get(0)).getId());
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check execution:
+ // Two subsections, each containing two sub-subsections with one source each
+ assertEquals(2,result.hits().size());
+ HitGroup row1=(HitGroup)result.hits().get(0);
+ HitGroup column11=(HitGroup)row1.get(0);
+ HitGroup column12=(HitGroup)row1.get(1);
+ HitGroup row2=(HitGroup)result.hits().get(1);
+ HitGroup column21a=(HitGroup)row2.get(0);
+ HitGroup column21b=(HitGroup)row2.get(1);
+ HitGroup column22=(HitGroup)row2.get(2);
+ assertEqualHitGroups(createHits("source1",3),column11);
+ assertEqualHitGroups(createHits("source2",4),column12);
+ assertEqualHitGroups(createHits("source3",5),column21a);
+ assertEqualHitGroups(createHits("source5",7),column21b);
+ assertEqualHitGroups(createHits("source4",6),column22);
+
+ // Check rendering
+ assertRendered(result,"MapSectionsToSectionsResult.xml");
+ }
+
+ /** Same as deterministic resolver, but asserts that it received the correct method names for each map choice */
+ private static class DeterministicResolverAssertingMethod extends DeterministicResolver {
+
+ /** Chooses the last alternative of any choice */
+ @Override
+ public void resolve(MapChoice mapChoice, Query query, Result result, Resolution resolution) {
+ assertEquals("myMethod",mapChoice.getMethod());
+ super.resolve(mapChoice,query,result,resolution);
+ }
+
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml
new file mode 100644
index 00000000000..7b5c0770096
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSections.xml
@@ -0,0 +1,22 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="MapSourcesToSections" layout="column" description="4 sources are assigned to a section each">
+
+ <section layout="row" description="row 1">
+ <section id="box1"><placeholder id="box1source"/></section>
+ <section id="box2"><placeholder id="box2source"/></section>
+ </section>
+ <section layout="row" description="row 2">
+ <section id="box3"><placeholder id="box3source"/></section>
+ <section id="box4"><placeholder id="box4source"/></section>
+ </section>
+
+ <choice method="myMethod">
+ <map to="box1source box2source box3source box4source">
+ <source name="source1"/>
+ <source name="source2"/>
+ <source name="source3"/>
+ <source name="source4"/>
+ </map>
+ </choice>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml
new file mode 100644
index 00000000000..034330c071c
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsResult.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0" layout="column">
+
+ <section layout="row">
+ <section id="section:box1">
+ <hit relevance="1.0" source="source1">
+ <id>source1-1</id>
+ </hit>
+ <hit relevance="0.5" source="source1">
+ <id>source1-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source1">
+ <id>source1-3</id>
+ </hit>
+ </section>
+ <section id="section:box2">
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+ <hit relevance="0.25" source="source2">
+ <id>source2-4</id>
+ </hit>
+ </section>
+ </section>
+
+ <section layout="row">
+ <section id="section:box3">
+ <hit relevance="1.0" source="source3">
+ <id>source3-1</id>
+ </hit>
+ <hit relevance="0.5" source="source3">
+ <id>source3-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source3">
+ <id>source3-3</id>
+ </hit>
+ <hit relevance="0.25" source="source3">
+ <id>source3-4</id>
+ </hit>
+ <hit relevance="0.2" source="source3">
+ <id>source3-5</id>
+ </hit>
+ </section>
+ <section id="section:box4">
+ <hit relevance="1.0" source="source4">
+ <id>source4-1</id>
+ </hit>
+ <hit relevance="0.5" source="source4">
+ <id>source4-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source4">
+ <id>source4-3</id>
+ </hit>
+ <hit relevance="0.25" source="source4">
+ <id>source4-4</id>
+ </hit>
+ <hit relevance="0.2" source="source4">
+ <id>source4-5</id>
+ </hit>
+ <hit relevance="0.1666666666666667" source="source4">
+ <id>source4-6</id>
+ </hit>
+ </section>
+ </section>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java
new file mode 100644
index 00000000000..49cc0411ac5
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/MapSourcesToSectionsTestCase.java
@@ -0,0 +1,88 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.PageTemplate;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.pagetemplates.model.MapChoice;
+import com.yahoo.search.pagetemplates.model.PageElement;
+import com.yahoo.search.pagetemplates.model.Source;
+import com.yahoo.search.result.HitGroup;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class MapSourcesToSectionsTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("MapSourcesToSections.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",4));
+ result.hits().add(createHits("source3",5));
+ result.hits().add(createHits("source4",6));
+ result.hits().add(createHits("source5",7));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolverAssertingMethod();
+ Resolution resolution=resolver.resolve(page,query,result);
+ Map<String, List<PageElement>> mapping=
+ resolution.getResolution((MapChoice)((PageTemplate)page.get(0).get(0)).getSection().elements().get(2));
+ assertNotNull(mapping);
+ assertEquals("source1",((Source)mapping.get("box1source").get(0)).getName());
+ assertEquals("source2",((Source)mapping.get("box2source").get(0)).getName());
+ assertEquals("source3",((Source)mapping.get("box3source").get(0)).getName());
+ assertEquals("source4",((Source)mapping.get("box4source").get(0)).getName());
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check execution:
+ // Two subsections, each containing two sub-subsections with one source each
+ assertEquals(2,result.hits().size());
+ HitGroup row1=(HitGroup)result.hits().get(0);
+ HitGroup column11=(HitGroup)row1.get(0);
+ HitGroup column12=(HitGroup)row1.get(1);
+ HitGroup row2=(HitGroup)result.hits().get(1);
+ HitGroup column21=(HitGroup)row2.get(0);
+ HitGroup column22=(HitGroup)row2.get(1);
+ assertEqualHitGroups(createHits("source1",3),column11);
+ assertEqualHitGroups(createHits("source2",4),column12);
+ assertEqualHitGroups(createHits("source3",5),column21);
+ assertEqualHitGroups(createHits("source4",6),column22);
+
+ // Check rendering
+ assertRendered(result,"MapSourcesToSectionsResult.xml");
+ }
+
+ /** Same as deterministic resolver, but asserts that it received the correct method names for each map choice */
+ private static class DeterministicResolverAssertingMethod extends DeterministicResolver {
+
+ /** Chooses the last alternative of any choice */
+ @Override
+ public void resolve(MapChoice mapChoice, Query query, Result result, Resolution resolution) {
+ assertEquals("myMethod",mapChoice.getMethod());
+ super.resolve(mapChoice,query,result,resolution);
+ }
+
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml
new file mode 100644
index 00000000000..967da527b6e
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/Page.xml
@@ -0,0 +1,31 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="Page">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+
+ <section region="1" source="news">
+ <renderer name="articleListRenderer"/>
+ </section>
+
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+
+ <section region="3" source="htmlSource">
+ <renderer name="htmlRenderer"/>
+ </section>
+ </section>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml
new file mode 100644
index 00000000000..95b86ef1f4d
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageResult.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page version="1.0">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+ <section region="1">
+ <renderer name="articleListRenderer"/>
+ <content>
+ <hit relevance="1.0" source="news">
+ <id>news-1</id>
+ </hit>
+ <hit relevance="0.5" source="news">
+ <id>news-2</id>
+ </hit>
+ </content>
+ </section>
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+ <section region="3">
+ <renderer name="htmlRenderer"/>
+ <content>
+ <hit relevance="1.0" source="htmlSource">
+ <id>htmlSource-1</id>
+ </hit>
+ </content>
+ </section>
+ </section>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java
new file mode 100644
index 00000000000..33930f3d0e0
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageTestCase.java
@@ -0,0 +1,44 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.prelude.templates.PageTemplateSet;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import org.junit.Test;
+
+/**
+ * Tests an example page.
+ *
+ * @author bratseth
+ */
+public class PageTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("Page.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("news",2));
+ result.hits().add(createHits("htmlSource",1));
+
+ // Resolve (noop here)
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check rendering
+ assertRendered(result,"PageResult.xml",new PageTemplateSet());
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml
new file mode 100644
index 00000000000..dca31eb42e1
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlending.xml
@@ -0,0 +1,37 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="PageWithBlending">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+
+ <section region="1">
+ <renderer for="newsImage" name="newsImageRenderer"/>
+ <source name="news">
+ <renderer name="articleRenderer"/>
+ </source>
+ <source name="image">
+ <renderer name="imageRenderer"/>
+ </source>
+ </section>
+
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+
+ <section region="3" source="htmlSource">
+ <renderer name="htmlRenderer"/>
+ </section>
+ </section>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml
new file mode 100644
index 00000000000..7ac78f3e820
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingResult.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page version="1.0">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+ <section region="1">
+ <renderer for="newsImage" name="newsImageRenderer"/>
+ <renderer for="news" name="articleRenderer"/>
+ <renderer for="image" name="imageRenderer"/>
+ <content>
+ <hit relevance="1.0" source="news">
+ <id>news-1</id>
+ </hit>
+ <hit relevance="0.5" source="news">
+ <id>news-2</id>
+ </hit>
+ </content>
+ </section>
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+ <section region="3">
+ <renderer name="htmlRenderer"/>
+ <content>
+ <hit relevance="1.0" source="htmlSource">
+ <id>htmlSource-1</id>
+ </hit>
+ </content>
+ </section>
+ </section>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java
new file mode 100644
index 00000000000..445105cfd2f
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithBlendingTestCase.java
@@ -0,0 +1,44 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.prelude.templates.PageTemplateSet;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import org.junit.Test;
+
+/**
+ * Tests an exapnded example.
+ *
+ * @author bratseth
+ */
+public class PageWithBlendingTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("PageWithBlending.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("news",2));
+ result.hits().add(createHits("htmlSource",1));
+
+ // Resolve (noop here)
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check rendering
+ assertRendered(result,"PageWithBlendingResult.xml",new PageTemplateSet());
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml
new file mode 100644
index 00000000000..5d3e38c2beb
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRenderer.xml
@@ -0,0 +1,36 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="PageWithSourceRenderer">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <choice>
+ <source url="notchosen"/>
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ </choice>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+
+ <section region="1">
+ <source name="news">
+ <renderer name="articleRenderer"/>
+ </source>
+ </section>
+
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+
+ <section region="3" source="htmlSource">
+ <renderer name="htmlRenderer"/>
+ </section>
+ </section>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml
new file mode 100644
index 00000000000..00656399331
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererResult.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page version="1.0">
+
+ <renderer name="two-column"/>
+
+ <section region="left">
+ <source url="http://carmot.yahoo.com:4080/resource/[news article id]"/>
+ <renderer name="articleBodyRenderer">
+ <parameter name="color">blue</parameter>
+ </renderer>
+ </section>
+
+ <section region="right">
+ <renderer name="multi-item-column">
+ <parameter name="items">3</parameter>
+ </renderer>
+ <section region="1">
+ <renderer for="news" name="articleRenderer"/>
+ <content>
+ <hit relevance="1.0" source="news">
+ <id>news-1</id>
+ </hit>
+ <hit relevance="0.5" source="news">
+ <id>news-2</id>
+ </hit>
+ </content>
+ </section>
+ <section region="2">
+ <source url="http://vitality.yahoo.com:4080/consumption-widget"/>
+ <renderer name="identityRenderer"/>
+ </section>
+ <section region="3">
+ <renderer name="htmlRenderer"/>
+ <content>
+ <hit relevance="1.0" source="htmlSource">
+ <id>htmlSource-1</id>
+ </hit>
+ </content>
+ </section>
+ </section>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java
new file mode 100644
index 00000000000..e7dbae21d47
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/PageWithSourceRendererTestCase.java
@@ -0,0 +1,44 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.prelude.templates.PageTemplateSet;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import org.junit.Test;
+
+/**
+ * Tests an example with two data sources with a renderer each.
+ *
+ * @author bratseth
+ */
+public class PageWithSourceRendererTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("PageWithSourceRenderer.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("news",2));
+ result.hits().add(createHits("htmlSource",1));
+
+ // Resolve
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check rendering
+ assertRendered(result,"PageWithSourceRendererResult.xml",new PageTemplateSet());
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml
new file mode 100644
index 00000000000..ff39ef1d3d1
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoice.xml
@@ -0,0 +1,7 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="SourceChoice">
+ <choice>
+ <source name="news"/>
+ <source name="web"/>
+ </choice>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml
new file mode 100644
index 00000000000..c9e0909a476
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceResult.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page version="1.0">
+
+ <content>
+ <hit relevance="1.0" source="web">
+ <id>web-1</id>
+ </hit>
+ <hit relevance="0.5" source="web">
+ <id>web-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="web">
+ <id>web-3</id>
+ </hit>
+ </content>
+
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java
new file mode 100644
index 00000000000..04e550a631c
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/SourceChoiceTestCase.java
@@ -0,0 +1,43 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.prelude.templates.PageTemplateSet;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.Resolution;
+import com.yahoo.search.pagetemplates.engine.Resolver;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class SourceChoiceTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("SourceChoice.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("web",3));
+ result.hits().add(createHits("news",3));
+ result.hits().add(createHits("blog",3));
+
+ // Resolve (noop here)
+ Resolver resolver=new DeterministicResolver();
+ Resolution resolution=resolver.resolve(page,query,result);
+
+ // Execute
+ Organizer organizer =new Organizer();
+ organizer.organize(page,resolution,result);
+
+ // Check rendering
+ assertRendered(result,"SourceChoiceResult.xml",new PageTemplateSet(),true);
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml
new file mode 100644
index 00000000000..36cace66ff7
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSources.xml
@@ -0,0 +1,5 @@
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<page id="TwoSectionsFourSources" layout="twoColumns">
+ <section source="source3 source1" order="[source]" max="8" region="left"/>
+ <section source="source4 source2" order="-[rank]" max="10" region="right"/>
+</page>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml
new file mode 100644
index 00000000000..0ca5bfc7ea0
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesResult.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<result version="1.0" layout="twoColumns">
+
+ <section region="left">
+ <hit relevance="1.0" source="source3">
+ <id>source3-1</id>
+ </hit>
+ <hit relevance="0.5" source="source3">
+ <id>source3-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source3">
+ <id>source3-3</id>
+ </hit>
+ <hit relevance="0.25" source="source3">
+ <id>source3-4</id>
+ </hit>
+ <hit relevance="0.2" source="source3">
+ <id>source3-5</id>
+ </hit>
+ <hit relevance="1.0" source="source1">
+ <id>source1-1</id>
+ </hit>
+ <hit relevance="0.5" source="source1">
+ <id>source1-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source1">
+ <id>source1-3</id>
+ </hit>
+ </section>
+
+ <section region="right">
+ <hit relevance="1.0" source="source4">
+ <id>source4-1</id>
+ </hit>
+ <hit relevance="1.0" source="source2">
+ <id>source2-1</id>
+ </hit>
+ <hit relevance="0.5" source="source4">
+ <id>source4-2</id>
+ </hit>
+ <hit relevance="0.5" source="source2">
+ <id>source2-2</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source4">
+ <id>source4-3</id>
+ </hit>
+ <hit relevance="0.3333333333333333" source="source2">
+ <id>source2-3</id>
+ </hit>
+ <hit relevance="0.25" source="source4">
+ <id>source4-4</id>
+ </hit>
+ <hit relevance="0.25" source="source2">
+ <id>source2-4</id>
+ </hit>
+ <hit relevance="0.2" source="source4">
+ <id>source4-5</id>
+ </hit>
+ <hit relevance="0.1666666666666667" source="source4">
+ <id>source4-6</id>
+ </hit>
+ </section>
+
+</result>
diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java
new file mode 100644
index 00000000000..3fff2103332
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/TwoSectionsFourSourcesTestCase.java
@@ -0,0 +1,140 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.pagetemplates.engine.test;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.pagetemplates.engine.Organizer;
+import com.yahoo.search.pagetemplates.engine.resolvers.DeterministicResolver;
+import com.yahoo.search.pagetemplates.model.Choice;
+import com.yahoo.search.result.Hit;
+import com.yahoo.search.result.HitGroup;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+public class TwoSectionsFourSourcesTestCase extends ExecutionAbstractTestCase {
+
+ @Test
+ public void testExecution() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source2",4));
+ result.hits().add(createHits("source3",12));
+ result.hits().add(createHits("source4",13));
+
+ new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result);
+
+ // Check execution:
+ // Two subsections with two sources each, the first grouped the second blended
+ assertEquals(2,result.hits().size());
+ HitGroup section1=(HitGroup)result.hits().get(0);
+ HitGroup section2=(HitGroup)result.hits().get(1);
+ assertGroupedSource3Source1(section1.asList());
+ assertBlendedSource4Source2(section2.asList());
+
+ // Check rendering
+ assertRendered(result,"TwoSectionsFourSourcesResult.xml");
+ }
+
+ @Test
+ public void testExecutionMissingOneSource() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source3",12));
+ result.hits().add(createHits("source4",13));
+
+ new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result);
+
+ // Check execution:
+ // Two subsections with two sources each, the first grouped the second blended
+ assertEquals(2,result.hits().size());
+ HitGroup section1=(HitGroup)result.hits().get(0);
+ HitGroup section2=(HitGroup)result.hits().get(1);
+ assertGroupedSource3Source1(section1.asList());
+ assertEqualHitGroups(createHits("source4",10),section2);
+ }
+
+ @Test
+ public void testExecutionMissingTwoSources() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+ result.hits().add(createHits("source1",3));
+ result.hits().add(createHits("source3",12));
+
+ new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result);
+
+ // Check execution:
+ // Two subsections with two sources each, the first grouped the second blended
+ assertEquals(2,result.hits().size());
+ HitGroup section1=(HitGroup)result.hits().get(0);
+ HitGroup section2=(HitGroup)result.hits().get(1);
+ assertGroupedSource3Source1(section1.asList());
+ assertEquals(0,section2.size());
+ }
+
+ @Test
+ public void testExecutionMissingAllSources() {
+ // Create the page template
+ Choice page=Choice.createSingleton(importPage("TwoSectionsFourSources.xml"));
+
+ // Create a federated result
+ Query query=new Query();
+ Result result=new Result(query);
+
+ new Organizer().organize(page,new DeterministicResolver().resolve(page,query,result),result);
+
+ // Check execution:
+ // Two subsections with two sources each, the first grouped the second blended
+ assertEquals(2,result.hits().size());
+ HitGroup section1=(HitGroup)result.hits().get(0);
+ HitGroup section2=(HitGroup)result.hits().get(1);
+ assertEquals(0,section1.size());
+ assertEquals(0,section2.size());
+ }
+
+ private void assertGroupedSource3Source1(List<Hit> hits) {
+ assertEquals(8,hits.size());
+ assertEquals("source3-1",hits.get(0).getId().stringValue());
+ assertEquals("source3-2",hits.get(1).getId().stringValue());
+ assertEquals("source3-3",hits.get(2).getId().stringValue());
+ assertEquals("source3-4",hits.get(3).getId().stringValue());
+ assertEquals("source3-5",hits.get(4).getId().stringValue());
+ assertEquals("source1-1",hits.get(5).getId().stringValue());
+ assertEquals("source1-2",hits.get(6).getId().stringValue());
+ assertEquals("source1-3",hits.get(7).getId().stringValue());
+ }
+
+ private void assertBlendedSource4Source2(List<Hit> hits) {
+ assertEquals(10,hits.size());
+ assertEquals("source4-1",hits.get(0).getId().stringValue());
+ assertEquals("source2-1",hits.get(1).getId().stringValue());
+ assertEquals("source4-2",hits.get(2).getId().stringValue());
+ assertEquals("source2-2",hits.get(3).getId().stringValue());
+ assertEquals("source4-3",hits.get(4).getId().stringValue());
+ assertEquals("source2-3",hits.get(5).getId().stringValue());
+ assertEquals("source4-4",hits.get(6).getId().stringValue());
+ assertEquals("source2-4",hits.get(7).getId().stringValue());
+ assertEquals("source4-5",hits.get(8).getId().stringValue());
+ assertEquals("source4-6",hits.get(9).getId().stringValue());
+ }
+
+}