<commit_before>package org.basex.tests.w3c;

import org.basex.core.Context;
import org.basex.core.MainProp;
import org.basex.core.Prop;
import static org.basex.core.Prop.NL;
import org.basex.core.Text;
import org.basex.core.cmd.Set;
import org.basex.io.IO;
import org.basex.io.IOFile;
import org.basex.io.out.PrintOutput;
import org.basex.query.QueryProcessor;
import org.basex.query.func.Function;
import org.basex.query.item.SeqType;
import org.basex.query.item.Str;
import org.basex.query.util.Compare.Flag;
import static org.basex.tests.w3c.QT3Constants.*;
import org.basex.tests.w3c.qt3api.*;
import org.basex.util.Args;
import org.basex.util.Performance;
import static org.basex.util.Token.*;
import org.basex.util.TokenBuilder;
import org.basex.util.Util;
import org.basex.util.list.ObjList;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;

/**
 * Driver for the XQuery/XPath/XSLT 3.* Test Suite, located at
 * {@code http://dev.w3.org/2011/QT3-test-suite/}.
 *
 * @author BaseX Team 2005-12, BSD License
 * @author <NAME>
 */
public final class QT3TS {
  /** Default path to the test suite. */
  protected static final String PATH = "g:/XML/w3c/qt3ts/";

  /** Maximum length of result output. */
  private int maxout = 2000;

  /** Correct results. */
  private final TokenBuilder right = new TokenBuilder();
  /** Wrong results. */
  private final TokenBuilder wrong = new TokenBuilder();
  /** Ignored tests. */
  private final TokenBuilder ignore = new TokenBuilder();

  /** Number of total queries. */
  private int total;
  /** Number of tested queries. */
  private int tested;
  /** Number of correct queries. */
  private int correct;
  /** Number of ignored queries. */
  private int ignored;

  /** Current base uri. */
  private String base;

  /** Query filter string. */
  private String single = "";
  /** Verbose flag. */
  private boolean verbose;
  /** Error code flag. */
  private boolean errors;
  /** Also print ignored files. */
  private boolean ignoring;
  /** All flag. */
  private boolean all;

  /** Database context. */
  protected final Context ctx = new Context();
  /** Global environments. */
  private final ObjList<QT3Env> genvs = new ObjList<QT3Env>();

  /**
   * Main method of the test class.
   * @param args command-line arguments
   * @throws Exception exception
   */
  public static void main(final String[] args) throws Exception {
    try {
      new QT3TS().run(args);
    } catch(final IOException ex) {
      Util.errln(ex);
      System.exit(1);
    }
  }

  /**
   * Runs all tests.
   * @param args command-line arguments
   * @throws Exception exception
   */
  private void run(final String[] args) throws Exception {
    parseArguments(args);

    final Performance perf = new Performance();
    new Set(Prop.CHOP, false).execute(ctx);
    new Set(Prop.INTPARSE, false).execute(ctx);

    final XQuery qdoc = new XQuery("doc(' " + PATH + '/' + CATALOG + "')", ctx);
    final XQValue doc = qdoc.value();
    final String version = asString("*:catalog/@version", doc);
    Util.outln(NL + "QT3 Test Suite " + version);
    Util.out("Parsing queries");

    final XQuery qenv = new XQuery("*:catalog/*:environment", ctx).context(doc);
    for(final XQItem ienv : qenv) genvs.add(new QT3Env(ctx, ienv));
    qenv.close();

    final XQuery qset = new XQuery(
        "for $f in //*:test-set/@file return string($f)", ctx).context(doc);
    for(final XQItem it : qset) testSet(it.getString());
    qset.close();
    qdoc.close();

    final StringBuilder result = new StringBuilder();
    result.append(" Rate    : ").append(pc(correct, tested)).append(NL);
    result.append(" Correct : ").append(correct).append(NL);
    result.append(" Tested  : ").append(tested).append(NL);
    result.append(" Total   : ").append(total).append(NL);
    result.append(" Ignored : ").append(ignored).append(NL);

    Util.outln(NL + "Writing log file..." + NL);
    final PrintOutput po = new PrintOutput(PATH + "qt3ts.log");
    po.println("QT3TS RESULTS __________________________" + NL);
    po.println(result.toString());
    po.println("WRONG __________________________________" + NL);
    po.print(wrong.finish());
    if(all || !single.isEmpty()) {
      po.println("CORRECT ________________________________" + NL);
      po.print(right.finish());
    }
    if(ignoring) {
      po.println("IGNORED ________________________________" + NL);
      po.print(ignore.finish());
    }
    po.close();

    Util.out(result);
    Util.outln(" Time    : " + perf);
  }

  /**
   * Runs a single test set.
   * @param name name of test set
   * @throws Exception exception
   */
  private void testSet(final String name) throws Exception {
    final XQuery qdoc = new XQuery("doc(' " + PATH + '/' + name + "')", ctx);
    final XQValue doc = qdoc.value();
    final XQuery qset = new XQuery("*:test-set", ctx).context(doc);
    final XQValue set = qset.value();
    base = IO.get(doc.getBaseURI()).dir();
    qdoc.close();

    if(supported(set)) {
      // parse environment of test-set
      final XQuery qenv = new XQuery("*:environment", ctx).context(set);
      final ObjList<QT3Env> envs = new ObjList<QT3Env>();
      for(final XQItem ienv : qenv) envs.add(new QT3Env(ctx, ienv));
      qenv.close();

      // run all test cases
      final XQuery qts = new XQuery("*:test-case", ctx).context(set);
      for(final XQItem its : qts) {
        try {
          testCase(its, envs);
        } catch(final IOException ex) {
          Util.debug(ex);
        }
      }
      qts.close();
    }
    qset.close();
  }

  /**
   * Runs a single test case.
   * @param test node
   * @param envs environments
   * @throws Exception exception
   */
  private void testCase(final XQItem test, final ObjList<QT3Env> envs)
      throws Exception {

    if(total++ % 500 == 0) Util.out(".");

    if(!supported(test)) {
      if(ignoring) ignore.add(asString("@name", test)).add(NL);
      ignored++;
      return;
    }

    // skip queries that do not match filter
    final String name = asString("@name", test);
    if(!name.startsWith(single)) {
      if(ignoring) ignore.add(name).add(NL);
      ignored++;
      return;
    }

    tested++;

    // expected result
    final XQuery qexp = new XQuery("*:result/*[1]", ctx).context(test);
    final XQValue expected = qexp.value();

    // use XQuery 1.0 if XQ10 or XP20 is specified
    final XQuery q = new XQuery("*:dependency[@type='spec']" +
        "[matches(@value,'(XQ10|XP20)([^+]|$)')]", ctx);
    if(q.context(test).next() != null) ctx.prop.set(Prop.XQUERY3, false);
    q.close();

    // check if environment is defined in test-case
    QT3Env e = null;
    final XQuery qenv = new XQuery("*:environment[*]", ctx).context(test);
    final XQValue ienv = qenv.next();
    if(ienv != null) e = new QT3Env(ctx, ienv);
    qenv.close();

    // set base uri
    String b = base;
    if(e == null) {
      final String env = asString("*:environment/@ref", test);
      if(!env.isEmpty()) {
        // check if environment is defined in test-set
        e = envs(envs, env);
        // check if environment is defined in catalog
        if(e == null) {
          e = envs(genvs, env);
          b = null;
        }
        if(e == null) Util.errln("%: environment '%' not found.", name, env);
      }
    }

    // retrieve query to be run
    final Performance perf = new Performance();
    final String qfile = asString("*:test/@file", test);
    String string;
    if(qfile.isEmpty()) {
      // get query string
      string = asString("*:test", test);
    } else {
      // get query from file
      string = string(new IOFile(base, qfile).read());
    }

    final XQuery query = new XQuery(string, ctx);
    if(b != null) query.baseURI(b);

    // add modules
    final XQuery qmod = new XQuery(
        "for $m in *:module return ($m/@uri, $m/@file)", ctx).context(test);
    while(true) {
      final XQItem uri = qmod.next();
      if(uri == null) break;
      final XQItem file = qmod.next();
      query.addModule(uri.getString(), base + file.getString());
    }<commit_msg>[MOD] QT3TS: prevent exception for buggy/incomplete test cases<commit_after>package org.basex.tests.w3c;

import org.basex.core.Context;
import org.basex.core.MainProp;
import org.basex.core.Prop;
import static org.basex.core.Prop.NL;
import org.basex.core.Text;
import org.basex.core.cmd.Set;
import org.basex.io.IO;
import org.basex.io.IOFile;
import org.basex.io.out.PrintOutput;
import org.basex.query.QueryProcessor;
import org.basex.query.func.Function;
import org.basex.query.item.SeqType;
import org.basex.query.item.Str;
import org.basex.query.util.Compare.Flag;
import static org.basex.tests.w3c.QT3Constants.*;
import org.basex.tests.w3c.qt3api.*;
import org.basex.util.Args;
import org.basex.util.Performance;
import static org.basex.util.Token.*;
import org.basex.util.TokenBuilder;
import org.basex.util.Util;
import org.basex.util.list.ObjList;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;

/**
 * Driver for the XQuery/XPath/XSLT 3.* Test Suite, located at
 * {@code http://dev.w3.org/2011/QT3-test-suite/}.
 *
 * @author BaseX Team 2005-12, BSD License
 * @author <NAME>
 */
public final class QT3TS {
  /** Default path to the test suite. */
  protected static final String PATH = "g:/XML/w3c/qt3ts/";

  /** Maximum length of result output. */
  private int maxout = 2000;

  /** Correct results. */
  private final TokenBuilder right = new TokenBuilder();
  /** Wrong results. */
  private final TokenBuilder wrong = new TokenBuilder();
  /** Ignored tests. */
  private final TokenBuilder ignore = new TokenBuilder();

  /** Number of total queries. */
  private int total;
  /** Number of tested queries. */
  private int tested;
  /** Number of correct queries. */
  private int correct;
  /** Number of ignored queries. */
  private int ignored;

  /** Current base uri. */
  private String base;

  /** Query filter string. */
  private String single = "";
  /** Verbose flag. */
  private boolean verbose;
  /** Error code flag. */
  private boolean errors;
  /** Also print ignored files. */
  private boolean ignoring;
  /** All flag. */
  private boolean all;

  /** Database context. */
  protected final Context ctx = new Context();
  /** Global environments. */
  private final ObjList<QT3Env> genvs = new ObjList<QT3Env>();

  /**
   * Main method of the test class.
   * @param args command-line arguments
   * @throws Exception exception
   */
  public static void main(final String[] args) throws Exception {
    try {
      new QT3TS().run(args);
    } catch(final IOException ex) {
      Util.errln(ex);
      System.exit(1);
    }
  }

  /**
   * Runs all tests.
   * @param args command-line arguments
   * @throws Exception exception
   */
  private void run(final String[] args) throws Exception {
    parseArguments(args);

    final Performance perf = new Performance();
    new Set(Prop.CHOP, false).execute(ctx);
    new Set(Prop.INTPARSE, false).execute(ctx);

    final XQuery qdoc = new XQuery("doc(' " + PATH + '/' + CATALOG + "')", ctx);
    final XQValue doc = qdoc.value();
    final String version = asString("*:catalog/@version", doc);
    Util.outln(NL + "QT3 Test Suite " + version);
    Util.out("Parsing queries");

    final XQuery qenv = new XQuery("*:catalog/*:environment", ctx).context(doc);
    for(final XQItem ienv : qenv) genvs.add(new QT3Env(ctx, ienv));
    qenv.close();

    final XQuery qset = new XQuery(
        "for $f in //*:test-set/@file return string($f)", ctx).context(doc);
    for(final XQItem it : qset) testSet(it.getString());
    qset.close();
    qdoc.close();

    final StringBuilder result = new StringBuilder();
    result.append(" Rate    : ").append(pc(correct, tested)).append(NL);
    result.append(" Correct : ").append(correct).append(NL);
    result.append(" Tested  : ").append(tested).append(NL);
    result.append(" Total   : ").append(total).append(NL);
    result.append(" Ignored : ").append(ignored).append(NL);

    Util.outln(NL + "Writing log file..." + NL);
    final PrintOutput po = new PrintOutput(PATH + "qt3ts.log");
    po.println("QT3TS RESULTS __________________________" + NL);
    po.println(result.toString());
    po.println("WRONG __________________________________" + NL);
    po.print(wrong.finish());
    if(all || !single.isEmpty()) {
      po.println("CORRECT ________________________________" + NL);
      po.print(right.finish());
    }
    if(ignoring) {
      po.println("IGNORED ________________________________" + NL);
      po.print(ignore.finish());
    }
    po.close();

    Util.out(result);
    Util.outln(" Time    : " + perf);
  }

  /**
   * Runs a single test set.
   * @param name name of test set
   * @throws Exception exception
   */
  private void testSet(final String name) throws Exception {
    final XQuery qdoc = new XQuery("doc(' " + PATH + '/' + name + "')", ctx);
    final XQValue doc = qdoc.value();
    final XQuery qset = new XQuery("*:test-set", ctx).context(doc);
    final XQValue set = qset.value();
    base = IO.get(doc.getBaseURI()).dir();
    qdoc.close();

    if(supported(set)) {
      // parse environment of test-set
      final XQuery qenv = new XQuery("*:environment", ctx).context(set);
      final ObjList<QT3Env> envs = new ObjList<QT3Env>();
      for(final XQItem ienv : qenv) envs.add(new QT3Env(ctx, ienv));
      qenv.close();

      // run all test cases
      final XQuery qts = new XQuery("*:test-case", ctx).context(set);
      for(final XQItem its : qts) {
        try {
          testCase(its, envs);
        } catch(final IOException ex) {
          Util.debug(ex);
        }
      }
      qts.close();
    }
    qset.close();
  }

  /**
   * Runs a single test case.
   * @param test node
   * @param envs environments
   * @throws Exception exception
   */
  private void testCase(final XQItem test, final ObjList<QT3Env> envs)
      throws Exception {

    if(total++ % 500 == 0) Util.out(".");

    if(!supported(test)) {
      if(ignoring) ignore.add(asString("@name", test)).add(NL);
      ignored++;
      return;
    }

    // skip queries that do not match filter
    final String name = asString("@name", test);
    if(!name.startsWith(single)) {
      if(ignoring) ignore.add(name).add(NL);
      ignored++;
      return;
    }

    tested++;

    // expected result
    final XQuery qexp = new XQuery("*:result/*[1]", ctx).context(test);
    final XQValue expected = qexp.value();

    // use XQuery 1.0 if XQ10 or XP20 is specified
    final XQuery q = new XQuery("*:dependency[@type='spec']" +
        "[matches(@value,'(XQ10|XP20)([^+]|$)')]", ctx);
    if(q.context(test).next() != null) ctx.prop.set(Prop.XQUERY3, false);
    q.close();

    // check if environment is defined in test-case
    QT3Env e = null;
    final XQuery qenv = new XQuery("*:environment[*]", ctx).context(test);
    final XQValue ienv = qenv.next();
    if(ienv != null) e = new QT3Env(ctx, ienv);
    qenv.close();

    // set base uri
    String b = base;
    if(e == null) {
      final String env = asString("*:environment/@ref", test);
      if(!env.isEmpty()) {
        // check if environment is defined in test-set
        e = envs(envs, env);
        // check if environment is defined in catalog
        if(e == null) {
          e = envs(genvs, env);
          b = null;
        }
        if(e == null) Util.errln("%: environment '%' not found.", name, env);
      }
    }

    // retrieve query to be run
    final Performance perf = new Performance();
    final String qfile = asString("*:test/@file", test);
    String string;
    if(qfile.isEmpty()) {
      // get query string
      string = asString("*:test", test);
    } else {
      // get query from file
      string = string(new IOFile(base, qfile).read());
    }

    final XQuery query = new XQuery(string, ctx);
    if(b != null) query.baseURI(b);

    // add modules
    final XQuery qmod = new XQuery(
        "for $m in *:module return ($m/@uri, $m/@file)", ctx).context(test);
    while(true) {
      final XQItem uri = qmod.next();
      if(uri == null) break;
      final XQItem file = qmod.next();
      if(file == null) break;
      query.addModule(uri.getString(), base + file.getString());
    }
{'fraction_non_alphanumeric': 0.15264415711747042, 'fraction_numerical': 0.006801887370549666, 'mean_word_length': 2.873724187040114, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4032943', 'n_tokens_mistral': 5332, 'n_tokens_neox': 5150, 'n_words': 1396}