org.opensextant.solrtexttagger.AbstractTaggerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.opensextant.solrtexttagger.AbstractTaggerTest.java

Source

/*
 This software was produced for the U. S. Government
 under Contract No. W15P7T-11-C-F600, and is
 subject to the Rights in Noncommercial Computer Software
 and Noncommercial Computer Software Documentation
 Clause 252.227-7014 (JUN 1995)
    
 Copyright 2013 The MITRE Corporation. All Rights Reserved.
    
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
    
 http://www.apache.org/licenses/LICENSE-2.0
    
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

package org.opensextant.solrtexttagger;

import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.lucene.document.Document;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ContentStream;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryRequestBase;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
import org.apache.solr.search.SolrIndexSearcher;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

/**
 * @author David Smiley - dsmiley@apache.org
 */
public abstract class AbstractTaggerTest extends SolrTestCaseJ4 {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    @Rule
    public TestWatcher watchman = new TestWatcher() {
        @Override
        protected void starting(Description description) {
            log.info("{} being run...", description.getDisplayName());
        }
    };

    protected final ModifiableSolrParams baseParams = new ModifiableSolrParams();

    //populated in buildNames; tested in assertTags
    protected static List<String> NAMES;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        baseParams.clear();
        baseParams.set(CommonParams.QT, "/tag");
    }

    protected void assertTags(String doc, String... tags) throws Exception {
        TestTag[] tts = new TestTag[tags.length];
        for (int i = 0; i < tags.length; i++) {
            tts[i] = tt(doc, tags[i]);
        }
        assertTags(reqDoc(doc), tts);
    }

    protected static void buildNames(String... names) throws Exception {
        deleteByQueryAndGetVersion("*:*", null);
        NAMES = Arrays.asList(names);
        //Collections.sort(NAMES);
        int i = 0;
        for (String n : NAMES) {
            assertU(adoc("id", "" + (i++), "name", n));
        }
        assertU(commit());
    }

    protected String lookupByName(String name) {
        for (String n : NAMES) {
            if (n.equalsIgnoreCase(name))
                return n;
        }
        return null;
    }

    protected TestTag tt(String doc, String substring) {
        int startOffset = -1, endOffset;
        int substringIndex = 0;
        for (int i = 0; i <= substringIndex; i++) {
            startOffset = doc.indexOf(substring, ++startOffset);
            assert startOffset >= 0 : "The test itself is broken";
        }
        endOffset = startOffset + substring.length();//1 greater (exclusive)
        return new TestTag(startOffset, endOffset, substring, lookupByName(substring));
    }

    /** Asserts the tags.  Will call req.close(). */
    protected void assertTags(SolrQueryRequest req, TestTag... eTags) throws Exception {
        try {
            SolrQueryResponse rsp = h.queryAndResponse(req.getParams().get(CommonParams.QT), req);
            TestTag[] aTags = pullTagsFromResponse(req, rsp);

            String message;
            if (aTags.length > 10)
                message = null;
            else
                message = Arrays.asList(aTags).toString();
            Arrays.sort(eTags);
            assertSortedArrayEquals(message, eTags, aTags);

        } finally {
            req.close();
        }
    }

    @SuppressWarnings("unchecked")
    protected TestTag[] pullTagsFromResponse(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException {
        NamedList rspValues = rsp.getValues();
        Map<String, String> matchingNames = new HashMap<>();
        SolrIndexSearcher searcher = req.getSearcher();
        DocList docList = (DocList) rspValues.get("response");
        DocIterator iter = docList.iterator();
        while (iter.hasNext()) {
            int docId = iter.next();
            Document doc = searcher.doc(docId);
            String id = doc.getField("id").stringValue();
            String name = lookupByName(doc.get("name"));
            assertEquals("looking for " + name, NAMES.indexOf(name) + "", id);
            matchingNames.put(id, name);
        }

        //build TestTag[] aTags from response ('a' is actual)
        List<NamedList> mTagsList = (List<NamedList>) rspValues.get("tags");
        TestTag[] aTags = new TestTag[mTagsList.size()];
        int mt_i = 0;
        for (NamedList map : mTagsList) {
            List<String> foundIds = (List<String>) map.get("ids");
            for (String id : foundIds) {
                aTags[mt_i++] = new TestTag(((Number) map.get("startOffset")).intValue(),
                        ((Number) map.get("endOffset")).intValue(), null, matchingNames.get(id));
            }
        }
        return aTags;
    }

    /** REMEMBER to close() the result req object. */
    protected SolrQueryRequest reqDoc(String doc, String... moreParams) {
        return reqDoc(doc, params(moreParams));
    }

    /** REMEMBER to close() the result req object. */
    protected SolrQueryRequest reqDoc(String doc, SolrParams moreParams) {
        log.debug("Test doc: " + doc);
        SolrParams params = SolrParams.wrapDefaults(moreParams, baseParams);
        SolrQueryRequestBase req = new SolrQueryRequestBase(h.getCore(), params) {
        };
        Iterable<ContentStream> stream = Collections
                .singleton((ContentStream) new ContentStreamBase.StringStream(doc));
        req.setContentStreams(stream);
        return req;
    }

    /** Asserts the sorted arrays are equals, with a helpful error message when not.
     * @param message
     * @param expecteds
     * @param actuals
     */
    public void assertSortedArrayEquals(String message, Object[] expecteds, Object[] actuals) {
        AssertionError error = null;
        try {
            assertArrayEquals(null, expecteds, actuals);
        } catch (AssertionError e) {
            error = e;
        }
        if (error == null)
            return;
        TreeSet<Object> expectedRemaining = new TreeSet<>(Arrays.asList(expecteds));
        expectedRemaining.removeAll(Arrays.asList(actuals));
        if (!expectedRemaining.isEmpty())
            fail(message + ": didn't find expected " + expectedRemaining.first() + " (of "
                    + expectedRemaining.size() + "); " + error);
        TreeSet<Object> actualsRemaining = new TreeSet<>(Arrays.asList(actuals));
        actualsRemaining.removeAll(Arrays.asList(expecteds));
        fail(message + ": didn't expect " + actualsRemaining.first() + " (of " + actualsRemaining.size() + "); "
                + error);
    }

    class TestTag implements Comparable {
        final int startOffset, endOffset;
        final String substring;
        final String docName;

        TestTag(int startOffset, int endOffset, String substring, String docName) {
            this.startOffset = startOffset;
            this.endOffset = endOffset;
            this.substring = substring;
            this.docName = docName;
        }

        @Override
        public String toString() {
            return "TestTag{" + "[" + startOffset + "-" + endOffset + "]" + " doc=" + NAMES.indexOf(docName) + ":'"
                    + docName + "'" + (docName.equals(substring) || substring == null ? "" : " substr=" + substring)
                    + '}';
        }

        @Override
        public boolean equals(Object obj) {
            TestTag that = (Tagger2Test.TestTag) obj;
            return new EqualsBuilder().append(this.startOffset, that.startOffset)
                    .append(this.endOffset, that.endOffset).append(this.docName, that.docName).isEquals();
        }

        @Override
        public int hashCode() {
            return startOffset;//cheesy but acceptable
        }

        @Override
        public int compareTo(Object o) {
            TestTag that = (Tagger2Test.TestTag) o;
            return new CompareToBuilder().append(this.startOffset, that.startOffset)
                    .append(this.endOffset, that.endOffset).append(this.docName, that.docName).toComparison();
        }
    }
}