/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

parcel TestLucy;

inert class Lucy::Test::TestUtils  {

    /** Return a Vector of Strings, each representing the content for a
     * document in the shared collection.
     */
    inert incremented Vector*
    doc_set();

    /** Testing-only TermQuery factory.
     */
    inert incremented TermQuery*
    make_term_query(const char *field, const char *term);

    /** Testing-only PhraseQuery factory.
     */
    inert incremented PhraseQuery*
    make_phrase_query(const char *field, ...);

    /** Testing-only LeafQuery factory.
     */
    inert incremented LeafQuery*
    make_leaf_query(const char *field, const char *term);

    /** Return a new NOTQuery, decrementing the refcount for
     * `negated_query`.
     */
    inert incremented NOTQuery*
    make_not_query(Query *negated_query);

    inert incremented RangeQuery*
    make_range_query(const char *field, const char *lower_term = NULL,
                     const char *upper_term = NULL,
                     bool include_lower = true,
                     bool include_upper = true);

    /** Return either an ORQuery or an ANDQuery depending on the value of
     * `boolop`.  Takes a NULL-terminated list of Query objects.
     * Decrements the refcounts of all supplied children, under the assumption
     * that they were created solely for inclusion within the aggregate query.
     */
    inert incremented PolyQuery*
    make_poly_query(uint32_t boolop, ...);

    /** Verify an Analyzer's transform, transform_text, and split methods.
     */
    inert void
    test_analyzer(TestBatchRunner *runner, Analyzer *analyzer, String *source,
                  Vector *expected, const char *message);

    /** Return the "modules" folder.
     *
     * If the folder cannot be found, return NULL.
     */
    inert incremented nullable FSFolder*
    modules_folder();
}

__C__

#define LUCY_TESTUTILS_BOOLOP_OR  1
#define LUCY_TESTUTILS_BOOLOP_AND 2
#ifdef LUCY_USE_SHORT_NAMES
  #define BOOLOP_OR        LUCY_TESTUTILS_BOOLOP_OR
  #define BOOLOP_AND       LUCY_TESTUTILS_BOOLOP_AND
#endif

__END_C__


