aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/prelude/semantics/test/InheritanceTestCase.java
blob: 6553c64e00dea13659524b977415d9ec38083b3c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.semantics.test;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import com.google.common.util.concurrent.MoreExecutors;
import com.yahoo.component.chain.Chain;
import com.yahoo.language.Linguistics;
import com.yahoo.language.simple.SimpleLinguistics;
import com.yahoo.search.Query;
import com.yahoo.prelude.semantics.RuleBase;
import com.yahoo.prelude.semantics.RuleBaseException;
import com.yahoo.prelude.semantics.SemanticSearcher;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
import com.yahoo.search.rendering.RendererRegistry;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.search.test.QueryTestCase;

/**
 * @author bratseth
 */
@SuppressWarnings("deprecation")
public class InheritanceTestCase extends junit.framework.TestCase {

    private final String root="src/test/java/com/yahoo/prelude/semantics/test/rulebases/";

    private RuleBase parent, child1, child2, grandchild;
    private SemanticSearcher searcher;

    public InheritanceTestCase(String name) throws Exception {
        super(name);
        parent=RuleBase.createFromFile(root + "inheritingrules/parent.sr",null);
        child1=RuleBase.createFromFile(root + "inheritingrules/child1.sr",null);
        child2=RuleBase.createFromFile(root + "inheritingrules/child2.sr",null);
        grandchild=RuleBase.createFromFile(root + "inheritingrules/grandchild.sr",null);
        grandchild.setDefault(true);

        searcher=new SemanticSearcher(parent,child1,child2,grandchild);
    }

    protected void assertSemantics(String result,String input,RuleBase base) {
        assertSemantics(result,input,base,0);
    }

    protected void assertSemantics(String result,String input,RuleBase base,int tracelevel) {
        Query query=new Query("?query=" + QueryTestCase.httpEncode(input));
        base.analyze(query,tracelevel);
        assertEquals(result, query.getModel().getQueryTree().getRoot().toString());
    }

    public void testInclusion() {
        assertTrue(grandchild.includes("child1"));
        assertTrue(grandchild.includes("child2"));
        assertTrue(grandchild.includes("parent"));
        assertTrue(grandchild.includes("grandfather"));
        assertTrue(grandchild.includes("grandmother"));
        assertFalse(grandchild.includes("nonexisting"));

        assertFalse(parent.includes("child1"));
        assertFalse(parent.includes("child2"));
        assertFalse(parent.includes("parent"));
        assertTrue(parent.includes("grandfather"));
        assertTrue(parent.includes("grandmother"));
    }

    public void testInclusionOrderAndContentDump() {
        StringTokenizer lines=new StringTokenizer(grandchild.toContentString(),"\n",false);
        assertEquals("vw -> audi",lines.nextToken());
        assertEquals("cars -> car",lines.nextToken());
        assertEquals("[brand] [vehicle] -> vehiclebrand:[brand]",lines.nextToken());
        assertEquals("vehiclebrand:bmw +> expensivetv",lines.nextToken());
        assertEquals("vehiclebrand:audi -> vehiclebrand:skoda",lines.nextToken());
        assertEquals("vehiclebrand:vw -> vehiclebrand:audi",lines.nextToken());
        assertEquals("causesphrase -> \"a produced phrase\"",lines.nextToken());
        assertEquals("[vehicle] :- car, motorcycle, bus",lines.nextToken());
        assertEquals("[brand] :- alfa, audi, bmw, skoda",lines.nextToken());
    }

    public void testParent() throws Exception {
        assertSemantics("vehiclebrand:audi","audi cars",parent);
        assertSemantics("vehiclebrand:alfa","alfa bus",parent);
        assertSemantics("AND vehiclebrand:bmw expensivetv","bmw motorcycle",parent);
        assertSemantics("AND vw car",       "vw cars",parent);
        assertSemantics("AND skoda car",    "skoda cars",parent);
    }

    public void testChild1() throws Exception {
        assertSemantics("vehiclebrand:skoda","audi cars",child1);
        assertSemantics("vehiclebrand:alfa", "alfa bus",child1);
        assertSemantics("AND vehiclebrand:bmw expensivetv","bmw motorcycle",child1);
        assertSemantics("vehiclebrand:skoda","vw cars",child1);
        assertSemantics("AND skoda car",     "skoda cars",child1);
    }

    public void testChild2() throws Exception {
        assertSemantics("vehiclebrand:audi","audi cars",child2);
        assertSemantics("vehiclebrand:alfa","alfa bus",child2);
        assertSemantics("AND vehiclebrand:bmw expensivetv","bmw motorcycle",child2);
        assertSemantics("AND vw car","vw cars",child2);
        assertSemantics("vehiclebrand:skoda","skoda cars",child2);
    }

    public void testGrandchild() throws Exception {
        assertSemantics("vehiclebrand:skoda","audi cars",grandchild);
        assertSemantics("vehiclebrand:alfa","alfa bus",grandchild);
        assertSemantics("AND vehiclebrand:bmw expensivetv","bmw motorcycle",grandchild);
        assertSemantics("vehiclebrand:skoda","vw cars",grandchild);
        assertSemantics("vehiclebrand:skoda","skoda cars",grandchild);
    }

    public void testRuleBaseNames() {
        assertEquals("parent",parent.getName());
        assertEquals("child1",child1.getName());
        assertEquals("child2",child2.getName());
        assertEquals("grandchild",grandchild.getName());
    }

    public void testSearcher() {
        assertSemantics("vehiclebrand:skoda","vw cars",   "");
        assertSemantics("vehiclebrand:skoda","vw cars",   "&rules.rulebase=grandchild");
        assertSemantics("vehiclebrand:skoda","vw cars",   "&rules.rulebase=grandchild.sd");
        try {
            assertSemantics("AND vw cars",       "vw cars",   "&rules.rulebase=doesntexist");
            fail("No exception on missing rule base");
        }
        catch (RuleBaseException e) {
            // Success
        }
        assertSemantics("AND vw cars",       "vw cars",   "&rules.rulebase=grandchild.sd&rules.off");
        assertSemantics("AND vw cars",       "vw cars",   "&rules.off");

        assertSemantics("AND vw car",        "vw cars",   "&rules.rulebase=child2");
        assertSemantics("vehiclebrand:skoda","skoda cars","&rules.rulebase=child2");

        assertSemantics("vehiclebrand:skoda","audi cars", "&rules.rulebase=child1");
        assertSemantics("vehiclebrand:skoda","vw cars",   "&rules.rulebase=child1");
        assertSemantics("AND skoda car",     "skoda cars","&rules.rulebase=child1");

        assertSemantics("AND vw car",        "vw cars",   "&rules.rulebase=parent");
        assertSemantics("AND skoda car",     "skoda cars","&rules.rulebase=parent");
    }

    protected void assertSemantics(String result,String input,String ruleSelection) {
        Query query=new Query("?query=" + QueryTestCase.httpEncode(input) + "&tracelevel=0&tracelevel.rules=0" + ruleSelection);
        doSearch(searcher, query, 0,10);
        assertEquals(result, query.getModel().getQueryTree().getRoot().toString());
    }

    private Result doSearch(Searcher searcher, Query query, int offset, int hits) {
        query.setOffset(offset);
        query.setHits(hits);
        return createExecution(searcher).search(query);
    }

    private Execution createExecution(Searcher searcher) {
        Execution.Context context = new Execution.Context(null, null, null, new RendererRegistry(MoreExecutors.directExecutor()), new SimpleLinguistics());
        return new Execution(chainedAsSearchChain(searcher), context);
    }

    private Chain<Searcher> chainedAsSearchChain(Searcher topOfChain) {
        List<Searcher> searchers = new ArrayList<>();
        searchers.add(topOfChain);
        return new Chain<>(searchers);
    }

}