Esempio n. 1
0
  /**
   * Retrieves the specified value. Throws an error if value cannot be read.
   *
   * @param key key
   * @param c expected type
   * @return result
   */
  private Object get(final Object[] key, final Class<?> c) {
    final Object entry = props.get(key[0].toString());
    if (entry == null) Util.notexpected("Property " + key[0] + " not defined.");

    final Class<?> cc = entry.getClass();
    if (c != cc) Util.notexpected("Property '" + key[0] + "' is a " + Util.name(cc));
    return entry;
  }
Esempio n. 2
0
 @Override
 public String toString() {
   final TokenBuilder tb = new TokenBuilder(Util.name(this) + '[');
   for (int i = 0; i < size; ++i) {
     if (i != 0) tb.add(", ");
     tb.add(list[i]);
   }
   return tb.add(']').toString();
 }
Esempio n. 3
0
 static {
   try {
     final Class<?>[] classes = Loader.load(IFileParser.class.getPackage(), IFileParser.class);
     for (final Class<?> c : classes) {
       final String name = Util.name(c);
       if (!REGISTRY.containsValue(c) && fallbackParser != c)
         Util.debug("Loading % ... FAILED", name);
     }
   } catch (final IOException ex) {
     Util.errln("Failed to load parsers (%)", ex.getMessage());
   }
 }
Esempio n. 4
0
 /**
  * Gets a parser implementation for given file suffix.
  *
  * @param suffix the file suffix to get the parser for
  * @return the parser implementation or {@code null} if no implementation is available
  * @throws ParserException if the parser could not be loaded
  */
 IFileParser getParser(final String suffix) throws ParserException {
   IFileParser instance = parserInstances.get(suffix);
   if (instance == null) {
     final Class<? extends IFileParser> clazz = REGISTRY.get(suffix);
     if (clazz != null) {
       instance = (IFileParser) Reflect.get(clazz);
       if (instance == null) {
         throw new ParserException("Failed to load " + Util.name(clazz) + " for suffix " + suffix);
       }
     }
     // put in hash map ... even if null
     parserInstances.put(suffix, instance);
   }
   return instance;
 }
Esempio n. 5
0
/**
 * General tests of the XQuery Update Facility implementation.
 *
 * @author BaseX Team 2005-12, BSD License
 * @author Lukas Kircher
 */
public final class UpdateTest extends AdvancedQueryTest {
  /** Test database name. */
  private static final String DB = Util.name(UpdateTest.class);
  /** Test document. */
  private static final String DOC = "src/test/resources/xmark.xml";

  /**
   * Creates a database.
   *
   * @param input input database string, if null, then use default.
   * @throws BaseXException database exception
   */
  private void createDB(final String input) throws BaseXException {
    new CreateDB(DB, input == null ? DOC : input).execute(CONTEXT);
  }

  /**
   * Text merging for a simple insert into statement.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging01() throws Exception {
    createDB(null);
    query("insert node 'foo' into //item[@id='item0']/location");
    query("(//item[@id='item0']/location/text())[1]", "United Statesfoo");
  }

  /**
   * Text merging for a simple insert into statement in combination with an insert before statement.
   * Checks if pre value shifts are taken into account.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging02() throws Exception {
    createDB(null);
    query(
        "insert node 'foo' into //item[@id='item0']/location,"
            + "insert node <a/> before //item[@id='item0']");
    query("(//item[@id='item0']/location/text())[1]", "United Statesfoo");
  }

  /**
   * Text merging test. Test 'insert into as first' and whether pre value shifts are taken into
   * account correctly.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging03() throws Exception {
    createDB(null);

    query(
        "let $i := //item[@id='item0'] return (insert node 'foo' as "
            + "first into $i/location, insert node 'foo' before $i/location, "
            + "insert node 'foo' into $i/quantity)");
    query(
        "let $i := //item[@id='item0'] return "
            + "(($i/location/text())[1], ($i/quantity/text())[1])",
        "fooUnited States1foo");
  }

  /**
   * Text merging for a simple insert into statement. Checks if pre value shifts are taken into
   * account.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging04() throws Exception {
    createDB(null);

    query("let $i := //item[@id='item0'] return insert node 'foo' " + "before $i/location/text()");
    query("let $i := //item[@id='item0'] return " + "($i/location/text())[1]", "fooUnited States");
  }

  /**
   * Text merging for a simple insert into statement. Checks if pre value shifts are taken into
   * account.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging05() throws Exception {
    createDB(null);

    query(
        "let $i := //item[@id='item0']/location return "
            + "(insert node 'foo' into $i, delete node $i/text())");
    query("//item[@id='item0']/location/text()", "foo");
  }

  /**
   * Text merging test.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging06() throws Exception {
    createDB(null);

    query(
        "let $i := //item[@id='item0']/location return "
            + "(insert node <n/> into $i, insert node 'foo' as last into $i)");
    query("let $i := //item[@id='item0']/location return " + "delete node $i/n");
    query("(//item[@id='item0']/location/text())[1]", "United Statesfoo");
  }

  /**
   * Text merging test.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging07() throws Exception {
    createDB(null);

    query("let $i := //item[@id='item0']/location return " + "insert node 'foo' after $i/text()");
    query("(//item[@id='item0']/location/text())[1]", "United Statesfoo");
  }

  /**
   * Text merging test.
   *
   * @throws Exception exception
   */
  @Test
  public void textMerging08() throws Exception {
    createDB(null);

    query("let $i := //item[@id='item0'] return " + "(insert node 'foo' after $i/location)");
    query(
        "let $i := //item[@id='item0']/location return "
            + "(insert node 'foo' after $i, insert node 'faa' before $i, insert "
            + "node 'faa' into $i, delete node $i/text())");
    query(
        "let $i := //item[@id='item0']/location " + "return ($i/text(), ($i/../text())[2])",
        "faafoofoo");
  }

  /** Text merging test for delete operation. */
  @Test
  public void textMerging09() {
    query(
        "copy $c := <n>aa<d/><d/>cc</n> "
            + "modify (delete node $c//d, insert node 'bb' after ($c//d)[1]) "
            + "return (count($c//text()), $c//text())",
        "1aabbcc");
  }

  /** Text merging test for delete operation. */
  @Test
  public void textMerging10() {
    query(
        "copy $c := <n>aa<d/><d/>cc</n> "
            + "modify (delete node $c//d, insert node 'bb' before ($c//d)[2]) "
            + "return (count($c//text()), $c//text())",
        "1aabbcc");
  }

  /** Text merging test for delete operation. */
  @Test
  public void textMerging11() {
    query(
        "copy $c := <n>aa<d/><d/>cc</n> "
            + "modify (delete node $c//d, insert node 'bb' before ($c//d)[2]) "
            + "return (count($c//text()), $c//text())",
        "1aabbcc");
  }

  /** Text merging test for delete operation. */
  @Test
  public void treeAwareUpdates() {
    query(
        "copy $n := <a><b><c/></b></a> "
            + "modify (replace value of node $n/b with (), "
            + "insert node <d/> into $n/b, insert node <d/> after $n/b) return $n",
        "<a><b/><d/></a>");
  }

  /** Delete last node of a data instance. Checks if table limits are crossed. */
  @Test
  public void deleteLastNode() {
    query("copy $n := <a><b/><c/></a> modify (delete node $n//c) return $n", "<a><b/></a>");
  }

  /** Replace last node of a data instance. Checks if table limits are crossed. */
  @Test
  public void replaceLastNode() {
    query(
        "copy $n := <a><b/><c><d/><d/><d/></c></a> "
            + "modify (replace node $n//c with <c/>) return $n",
        "<a><b/><c/></a>");
  }

  /**
   * Replaces the value of the documents root node. Related to github issue #141.
   *
   * @throws BaseXException database exception
   */
  @Test
  public void replaceValueOfEmptyRoot() throws BaseXException {
    createDB("<a/>");
    query("replace value of node /a with 'a'");
    query("/", "<a>a</a>");
  }

  /** Insertion into an empty element. */
  @Test
  public void emptyInsert1() {
    query("copy $x := <X/> modify insert nodes <A/> into $x return $x", "<X><A/></X>");
  }

  /** Insertion into an empty document. */
  @Test
  public void emptyInsert2() {
    query("copy $x := document {()} modify insert nodes <X/> into $x return $x", "<X/>");
  }

  /**
   * Insertion into an empty document.
   *
   * @throws BaseXException database exception
   */
  @Test
  public void emptyInsert3() throws BaseXException {
    createDB("<a/>");
    query("delete node /a");
    query("insert nodes <X/> into doc('" + DB + "')");
    query("/", "<X/>");
  }

  /**
   * Tests a simple call of the optimize command.
   *
   * @throws BaseXException database exception
   */
  @Test
  public void optimize() throws BaseXException {
    createDB(null);
    query(
        "let $w := //item[@id = 'item0'] "
            + "return (if($w/@id) "
            + "then (delete node $w/@id, db:optimize('"
            + DB
            + "')) else ())");
  }

  /** Variable from the inner scope shouldn't be visible. */
  @Test
  public void outOfScope() {
    error("let $d := copy $e := <a/> modify () return $e return $e", Err.VARUNDEF);
  }

  /** The new-namespace flag has to be set for the parent of an inserted attribute. */
  @Test
  public void setNSFlag() {
    query(
        "declare namespace x='x';"
            + "copy $x := <x/> modify insert node attribute x:x {} into $x return $x",
        "<x xmlns:x=\"x\" x:x=\"\"/>");
  }

  /** The new-namespace flag has to be set for the parent of an inserted attribute. */
  @Test
  public void setNSFlag2() {
    query(
        "declare namespace x='x';"
            + "copy $x := <x><a/></x> "
            + "modify insert node attribute x:x {} into $x return $x/a",
        "<a xmlns:x=\"x\"/>");
  }

  /** The new-namespace flag has to be set for the parent of an inserted attribute. */
  @Test
  public void setNSFlag3() {
    query(
        "declare namespace x='x';"
            + "copy $x := <x><a/></x> "
            + "modify insert node attribute x:x {} into $x/a return $x/a",
        "<a xmlns:x=\"x\" x:x=\"\"/>");
  }

  /**
   * Deletes the test db.
   *
   * @throws Exception exception
   */
  @AfterClass
  public static void end() throws Exception {
    new DropDB(DB).execute(CONTEXT);
    CONTEXT.close();
  }
}
Esempio n. 6
0
  /**
   * Runs the test suite.
   *
   * @param args command-line arguments
   * @throws Exception exception
   */
  void run(final String[] args) throws Exception {
    final Args arg =
        new Args(
            args,
            this,
            " Test Suite [options] [pat]"
                + NL
                + " [pat] perform only tests with the specified pattern"
                + NL
                + " -c     print compilation steps"
                + NL
                + " -h     show this help"
                + NL
                + " -m     minimum conformance"
                + NL
                + " -g     <test-group> test group to test"
                + NL
                + " -C     run tests depending on current time"
                + NL
                + " -p     change path"
                + NL
                + " -r     create report"
                + NL
                + " -t[ms] list slowest queries"
                + NL
                + " -v     verbose output");

    while (arg.more()) {
      if (arg.dash()) {
        final char c = arg.next();
        if (c == 'r') {
          reporting = true;
          currTime = true;
        } else if (c == 'C') {
          currTime = true;
        } else if (c == 'c') {
          compile = true;
        } else if (c == 'm') {
          minimum = true;
        } else if (c == 'g') {
          group = arg.string();
        } else if (c == 'p') {
          path = arg.string() + "/";
        } else if (c == 't') {
          timer = arg.num();
        } else if (c == 'v') {
          verbose = true;
        } else {
          arg.check(false);
        }
      } else {
        single = arg.string();
        maxout = Integer.MAX_VALUE;
      }
    }
    if (!arg.finish()) return;

    queries = path + "Queries/XQuery/";
    expected = path + "ExpectedTestResults/";
    results = path + "ReportingResults/Results/";
    report = path + "ReportingResults/";
    sources = path + "TestSources/";

    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    final String dat = sdf.format(Calendar.getInstance().getTime());

    final Performance perf = new Performance();
    context.prop.set(Prop.CHOP, false);

    // new Check(path + input).execute(context);
    data = CreateDB.xml(new IOFile(path + input), context);

    final Nodes root = new Nodes(0, data);
    Util.outln(NL + Util.name(this) + " Test Suite " + text("/*:test-suite/@version", root));

    Util.outln(NL + "Caching Sources...");
    for (final int s : nodes("//*:source", root).list) {
      final Nodes srcRoot = new Nodes(s, data);
      final String val = (path + text("@FileName", srcRoot)).replace('\\', '/');
      srcs.put(text("@ID", srcRoot), val);
    }

    Util.outln("Caching Modules...");
    for (final int s : nodes("//*:module", root).list) {
      final Nodes srcRoot = new Nodes(s, data);
      final String val = (path + text("@FileName", srcRoot)).replace('\\', '/');
      mods.put(text("@ID", srcRoot), val);
    }

    Util.outln("Caching Collections...");
    for (final int c : nodes("//*:collection", root).list) {
      final Nodes nodes = new Nodes(c, data);
      final String cname = text("@ID", nodes);

      final TokenList dl = new TokenList();
      final Nodes doc = nodes("*:input-document", nodes);
      for (int d = 0; d < doc.size(); ++d) {
        dl.add(token(sources + string(data.atom(doc.list[d])) + IO.XMLSUFFIX));
      }
      colls.put(cname, dl.toArray());
    }
    init(root);

    if (reporting) {
      Util.outln("Delete old results...");
      delete(new File[] {new File(results)});
    }

    if (verbose) Util.outln();
    final Nodes nodes =
        minimum
            ? nodes("//*:test-group[starts-with(@name, 'Minim')]//*:test-case", root)
            : group != null
                ? nodes("//*:test-group[@name eq '" + group + "']//*:test-case", root)
                : nodes("//*:test-case", root);

    long total = nodes.size();
    Util.out("Parsing " + total + " Queries");
    for (int t = 0; t < total; ++t) {
      if (!parse(new Nodes(nodes.list[t], data))) break;
      if (!verbose && t % 500 == 0) Util.out(".");
    }
    Util.outln();
    total = ok + ok2 + err + err2;

    final String time = perf.getTimer();
    Util.outln("Writing log file..." + NL);
    BufferedWriter bw =
        new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + pathlog), UTF8));
    bw.write("TEST RESULTS ==================================================");
    bw.write(NL + NL + "Total #Queries: " + total + NL);
    bw.write("Correct / Empty Results: " + ok + " / " + ok2 + NL);
    bw.write("Conformance (w/Empty Results): ");
    bw.write(pc(ok, total) + " / " + pc(ok + ok2, total) + NL);
    bw.write("Wrong Results / Errors: " + err + " / " + err2 + NL);
    bw.write("WRONG =========================================================");
    bw.write(NL + NL + logErr + NL);
    bw.write("WRONG (ERRORS) ================================================");
    bw.write(NL + NL + logErr2 + NL);
    bw.write("CORRECT? (EMPTY) ==============================================");
    bw.write(NL + NL + logOK2 + NL);
    bw.write("CORRECT =======================================================");
    bw.write(NL + NL + logOK + NL);
    bw.write("===============================================================");
    bw.close();

    bw = new BufferedWriter(new FileWriter(path + pathhis, true));
    bw.write(dat + "\t" + ok + "\t" + ok2 + "\t" + err + "\t" + err2 + NL);
    bw.close();

    if (reporting) {
      bw =
          new BufferedWriter(
              new OutputStreamWriter(new FileOutputStream(report + NAME + IO.XMLSUFFIX), UTF8));
      write(bw, report + NAME + "Pre" + IO.XMLSUFFIX);
      bw.write(logReport.toString());
      write(bw, report + NAME + "Pos" + IO.XMLSUFFIX);
      bw.close();
    }

    Util.outln("Total #Queries: " + total);
    Util.outln("Correct / Empty results: " + ok + " / " + ok2);
    Util.out("Conformance (w/empty results): ");
    Util.outln(pc(ok, total) + " / " + pc(ok + ok2, total));
    Util.outln("Total Time: " + time);

    context.close();
  }
Esempio n. 7
0
/**
 * This class tests namespaces.
 *
 * @author BaseX Team 2005-11, BSD License
 * @author Lukas Kircher
 */
public final class NamespaceTest {
  /** Database context. */
  private static final Context CONTEXT = new Context();
  /** Default database name. */
  private static final String DBNAME = Util.name(NamespaceTest.class);

  /** Test documents. */
  private static String[][] docs = {
    {"d1", "<x/>"},
    {"d2", "<x xmlns='xx'/>"},
    {"d3", "<a:x xmlns:a='aa'><b:y xmlns:b='bb'/></a:x>"},
    {"d4", "<a:x xmlns:a='aa'><a:y xmlns:b='bb'/></a:x>"},
    {"d5", "<a:x xmlns:a='aa'/>"},
    {"d6", "<a:x xmlns='xx' xmlns:a='aa'><a:y xmlns:b='bb'/></a:x>"},
    {"d7", "<x xmlns='xx'><y/></x>"},
    {"d8", "<a><b xmlns='B'/><c/></a>"},
    {"d9", "<a xmlns='A'><b><c/><d xmlns='D'/></b><e/></a>"},
    {"d10", "<a xmlns='A'><b><c/><d xmlns='D'><g xmlns='G'/></d></b><e/></a>"},
    {"d11", "<a xmlns='A'><b xmlns:ns1='AA'><d/></b><c xmlns:ns1='AA'>" + "<d/></c></a>"},
    {"d12", "<a><b/><c xmlns='B'/></a>"},
    {"d13", "<a><b xmlns='A'/></a>"},
    {"d14", "<a xmlns='A'><b xmlns='B'/><c xmlns='C'/></a>"},
    {"d15", "<a xmlns='A'><b xmlns='B'/><c xmlns='C'><d xmlns='D'/></c>" + "<e xmlns='E'/></a>"},
    {"d16", "<a><b/></a>"}
  };

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been inserted.
   *
   * @throws Exception exception
   */
  @Test
  public void insertIntoShiftPreValues() throws Exception {
    create(12);
    query("insert node <b xmlns:ns='A'/> into doc('d12')/*:a/*:b", "");
    new Open("d12").execute(CONTEXT);
    assertEquals(
        NL + "  Pre[3] xmlns:ns=\"A\" " + NL + "  Pre[4] xmlns=\"B\" ",
        CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been inserted.
   *
   * @throws Exception exception
   */
  @Test
  public void insertIntoShiftPreValues2() throws Exception {
    create(13);
    query("insert node <c/> as first into doc('d13')/a", "");
    new Open("d13").execute(CONTEXT);
    assertEquals(NL + "  Pre[3] xmlns=\"A\" ", CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been inserted.
   *
   * @throws Exception exception
   */
  @Test
  public void insertIntoShiftPreValues3() throws Exception {
    create(14);
    query("insert node <n xmlns='D'/> into doc('d14')/*:a/*:b", "");
    new Open("d14").execute(CONTEXT);
    assertEquals(
        NL
            + "  Pre[1] xmlns=\"A\" "
            + NL
            + "    Pre[2] xmlns=\"B\" "
            + NL
            + "      Pre[3] xmlns=\"D\" "
            + NL
            + "    Pre[4] xmlns=\"C\" ",
        CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been deleted.
   *
   * @throws Exception exception
   */
  @Test
  public void deleteShiftPreValues() throws Exception {
    create(12);
    query("delete node doc('d12')/a/b", "");
    new Open("d12").execute(CONTEXT);
    assertEquals(NL + "  Pre[2] xmlns=\"B\" ", CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been deleted.
   *
   * @throws Exception exception
   */
  @Test
  public void deleteShiftPreValues2() throws Exception {
    create(14);
    query("delete node doc('d14')/*:a/*:b", "");
    new Open("d14").execute(CONTEXT);
    assertEquals(
        NL + "  Pre[1] xmlns=\"A\" " + NL + "    Pre[2] xmlns=\"C\" ",
        CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been deleted.
   *
   * @throws Exception exception
   */
  @Test
  public void deleteShiftPreValues3() throws Exception {
    create(15);
    query("delete node doc('d15')/*:a/*:c", "");
    new Open("d15").execute(CONTEXT);
    assertEquals(
        NL
            + "  Pre[1] xmlns=\"A\" "
            + NL
            + "    Pre[2] xmlns=\"B\" "
            + NL
            + "    Pre[3] xmlns=\"E\" ",
        CONTEXT.data().ns.toString());
  }

  /**
   * Checks if namespace hierarchy structure is updated correctly on the descendant axis after a
   * NSNode has been deleted.
   *
   * @throws Exception exception
   */
  @Test
  public void deleteShiftPreValues4() throws Exception {
    create(16);
    query("delete node doc('d16')/a/b", "");
    new Open("d16").execute(CONTEXT);
    assertEquals("", CONTEXT.data().ns.toString());
  }

  /**
   * Tests for correct namespace hierarchy, esp. if namespace nodes on the following axis of an
   * insert/delete operation are updated correctly.
   *
   * @throws Exception exception
   */
  @Test
  public void delete1() throws Exception {
    create(11);
    query(
        "delete node doc('d11')/*:a/*:b",
        "doc('d11')/*:a",
        "<a xmlns='A'><c xmlns:ns1='AA'><d/></c></a>");
  }

  /** Test query. */
  @Test
  public void copy1() {
    query("copy $c := <x:a xmlns:x='xx'><b/></x:a>/b modify () return $c", "<b xmlns:x='xx'/>");
  }

  /**
   * Detects corrupt namespace hierarchy.
   *
   * @throws Exception exception
   */
  @Test
  public void copy2() throws Exception {
    create(4);
    query(
        "declare namespace a='aa'; copy $c:=doc('d4') modify () return $c//a:y",
        "<a:y xmlns:b='bb' xmlns:a='aa'/>");
  }

  /**
   * Detects missing prefix declaration.
   *
   * @throws Exception exception
   */
  @Test
  public void copy3() throws Exception {
    create(4);
    query(
        "declare namespace a='aa'; copy $c:=doc('d4')//a:y " + "modify () return $c",
        "<a:y xmlns:b='bb' xmlns:a='aa'/>");
  }

  /** Detects duplicate namespace declaration in MemData instance. */
  @Test
  public void copy4() {
    query(
        "copy $c := <a xmlns='test'><b><c/></b><d/></a> " + "modify () return $c",
        "<a xmlns='test'><b><c/></b><d/></a>");
  }

  /**
   * Detects bogus namespace after insert.
   *
   * @throws Exception exception
   */
  @Test
  public void bogusDetector() throws Exception {
    create(1);
    query(
        "insert node <a xmlns='test'><b><c/></b><d/></a> into doc('d1')/x",
        "declare namespace na = 'test';doc('d1')/x/na:a",
        "<a xmlns='test'><b><c/></b><d/></a>");
  }

  /** Detects empty default namespace in serializer. */
  @Test
  public void emptyDefaultNamespace() {
    query("<ns:x xmlns:ns='X'><y/></ns:x>", "<ns:x xmlns:ns='X'><y/></ns:x>");
  }

  /** Detects duplicate default namespace in serializer. */
  @Test
  public void duplicateDefaultNamespace() {
    query("<ns:x xmlns:ns='X'><y/></ns:x>", "<ns:x xmlns:ns='X'><y/></ns:x>");
  }

  /**
   * Detects malformed namespace hierarchy.
   *
   * @throws Exception exception
   */
  @Test
  public void nsHierarchy() throws Exception {
    create(9);
    query("insert node <f xmlns='F'/> into doc('d9')//*:e", "");
    new Open("d9").execute(CONTEXT);
    assertEquals(
        NL
            + "  Pre[1] xmlns=\"A\" "
            + NL
            + "    Pre[4] xmlns=\"D\" "
            + NL
            + "    Pre[6] xmlns=\"F\" ",
        CONTEXT.data().ns.toString());
  }

  /**
   * Detects malformed namespace hierarchy.
   *
   * @throws Exception exception
   */
  @Test
  public void nsHierarchy2() throws Exception {
    create(10);
    query("insert node <f xmlns='F'/> into doc('d10')//*:e", "");
    new Open("d10").execute(CONTEXT);
    assertEquals(
        NL
            + "  Pre[1] xmlns=\"A\" "
            + NL
            + "    Pre[4] xmlns=\"D\" "
            + NL
            + "      Pre[5] xmlns=\"G\" "
            + NL
            + "    Pre[7] xmlns=\"F\" ",
        CONTEXT.data().ns.toString());
  }

  /** Test query. */
  @Test
  public void copy5() {
    query(
        "copy $c := <n><a:y xmlns:a='aa'/><a:y xmlns:a='aa'/></n> " + "modify () return $c",
        "<n><a:y xmlns:a='aa'/><a:y xmlns:a='aa'/></n>");
  }

  /**
   * Test query.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD2intoD1() throws Exception {
    create(1, 2);
    query("insert node doc('d2') into doc('d1')/x", "doc('d1')", "<x><x xmlns='xx'/></x>");
  }

  /**
   * Test query.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD3intoD1() throws Exception {
    create(1, 3);
    query(
        "insert node doc('d3') into doc('d1')/x",
        "doc('d1')/x/*",
        "<a:x xmlns:a='aa'><b:y xmlns:b='bb'/></a:x>");
  }

  /**
   * Test query.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD3intoD1b() throws Exception {
    create(1, 3);
    query("insert node doc('d3') into doc('d1')/x", "doc('d1')/x/*/*", "<b:y xmlns:b='bb'/>");
  }

  /**
   * Detects missing prefix declaration.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD4intoD1() throws Exception {
    create(1, 4);
    query(
        "declare namespace a='aa'; insert node doc('d4')/a:x/a:y " + "into doc('d1')/x",
        "doc('d1')/x",
        "<x><a:y xmlns:a='aa' xmlns:b='bb'/></x>");
  }

  /**
   * Detects duplicate prefix declaration at pre=0 in MemData instance after insert. Though result
   * correct, prefix a is declared twice. -> Solution?
   *
   * @throws Exception exception
   */
  @Test
  public void insertD4intoD5() throws Exception {
    create(4, 5);
    query(
        "declare namespace a='aa';insert node doc('d4')//a:y " + "into doc('d5')/a:x",
        "declare namespace a='aa';doc('d5')//a:y",
        "<a:y xmlns:b='bb' xmlns:a='aa'/>");
  }

  /**
   * Detects duplicate namespace declarations in MemData instance.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD7intoD1() throws Exception {
    create(1, 7);
    query(
        "declare namespace x='xx';insert node doc('d7')/x:x into doc('d1')/x",
        "doc('d1')/x",
        "<x><x xmlns='xx'><y/></x></x>");
  }

  /**
   * Detects general problems with namespace references.
   *
   * @throws Exception exception
   */
  @Test
  public void insertD6intoD4() throws Exception {
    create(4, 6);
    query(
        "declare namespace a='aa';insert node doc('d6') into doc('d4')/a:x",
        "declare namespace a='aa';doc('d4')/a:x/a:y",
        "<a:y xmlns:b='bb' xmlns:a='aa'/>");
  }

  /** Detects general problems with namespace references. */
  @Test
  public void insertTransform1() {
    query(
        "declare default element namespace 'xyz';"
            + "copy $foo := <foo/> modify insert nodes (<bar/>, <baz/>)"
            + "into $foo return $foo",
        "<foo xmlns='xyz'><bar/><baz/></foo>");
  }

  /** Detects general problems with namespace references. */
  @Test
  public void insertTransformX() {
    query(
        "copy $foo := <foo/> modify insert nodes (<bar/>)" + "into $foo return $foo",
        "<foo><bar/></foo>");
  }

  /**
   * Detects wrong namespace references.
   *
   * @throws Exception exception
   */
  @Test
  public void uriStack() throws Exception {
    create(8);
    query("doc('d8')", "<a><b xmlns='B'/><c/></a>");
  }

  /**
   * Deletes the document node and checks if namespace nodes of descendants are deleted as well.
   * F.i. adding a document via JAX-RX/PUT deletes a document node if the given document/name is
   * already stored in the target collection. If the test fails, this may lead to superfluous
   * namespace nodes.
   *
   * @throws Exception exception
   */
  @Test
  public void deleteDocumentNode() throws Exception {
    new Open("d2").execute(CONTEXT);
    CONTEXT.data().delete(0);
    assertEquals(true, CONTEXT.data().ns.rootEmpty());
  }

  /**
   * Creates the database context.
   *
   * @throws BaseXException database exception
   */
  @BeforeClass
  public static void start() throws BaseXException {
    // turn off pretty printing
    new Set(Prop.SERIALIZER, "indent=no").execute(CONTEXT);
  }

  /**
   * Creates the specified test databases.
   *
   * @param db database numbers
   * @throws BaseXException database exception
   */
  public void create(final int... db) throws BaseXException {
    for (final int d : db) {
      final String[] doc = docs[d - 1];
      new CreateDB(doc[0], doc[1]).execute(CONTEXT);
    }
  }

  /**
   * Removes test databases and closes the database context.
   *
   * @throws BaseXException database exception
   */
  @AfterClass
  public static void finish() throws BaseXException {
    // drop all test databases
    for (final String[] db : docs) new DropDB(db[0]).execute(CONTEXT);
    new DropDB(DBNAME).execute(CONTEXT);
    CONTEXT.close();
  }

  /**
   * Runs a query and matches the result against the expected output.
   *
   * @param query query
   * @param expected expected output
   */
  private void query(final String query, final String expected) {
    query(null, query, expected);
  }

  /**
   * Runs an updating query and matches the result of the second query against the expected output.
   *
   * @param first first query
   * @param second second query
   * @param expected expected output
   */
  private void query(final String first, final String second, final String expected) {

    try {
      if (first != null) new XQuery(first).execute(CONTEXT);
      final String result = new XQuery(second).execute(CONTEXT);

      // quotes are replaced by apostrophes to simplify comparison
      final String res = result.replaceAll("\\\"", "'");
      final String exp = expected.replaceAll("\\\"", "'");
      if (!exp.equals(res)) fail("\nExpected: " + exp + "\nFound: " + res);
    } catch (final BaseXException ex) {
      fail(ex.getMessage());
    }
  }
}
Esempio n. 8
0
/**
 * This class tests the database commands.
 *
 * @author BaseX Team 2005-11, BSD License
 * @author Christian Gruen
 */
public class CommandTest {
  /** Database context. */
  protected static final Context CONTEXT = new Context();
  /** Test file name. */
  private static final String FN = "input.xml";
  /** Test folder. */
  private static final String FLDR = "etc/test";
  /** Test file. */
  private static final String FILE = FLDR + '/' + FN;
  /** Test name. */
  private static final String NAME = Util.name(CommandTest.class);
  /** Test name. */
  protected static final String NAME2 = NAME + '2';
  /** Socket reference. */
  static Session session;

  /**
   * Starts the server.
   *
   * @throws IOException I/O exception
   */
  @BeforeClass
  public static void start() throws IOException {
    session = new LocalSession(CONTEXT);
    cleanUp();
  }

  /**
   * Deletes the potentially already existing DBs. DBs & User {@link #NAME} and {@link #NAME2}
   *
   * @throws IOException I/O exception
   */
  protected static void cleanUp() throws IOException {
    session.execute(new DropDB(NAME));
    session.execute(new DropDB(NAME2));
    session.execute(new DropUser(NAME));
    session.execute(new DropUser(NAME2));
  }

  /** Removes test databases and closes the database context. */
  @AfterClass
  public static void finish() {
    CONTEXT.close();
  }

  /**
   * Creates the database.
   *
   * @throws IOException I/O exception
   */
  @After
  public final void after() throws IOException {
    cleanUp();
  }

  /** Command test. */
  @Test
  public final void add() {
    // database must be opened to add files
    no(new Add(FILE));
    ok(new CreateDB(NAME));
    ok(new Add(FILE, FN));
    ok(new Add(FILE, FN, "target"));
    no(new Add(FILE, "/"));
  }

  /** Command test. */
  @Test
  public final void alterDB() {
    ok(new CreateDB(NAME));
    ok(new AlterDB(NAME, NAME2));
    ok(new Close());
    no(new AlterDB(NAME, NAME2));
    no(new AlterDB(NAME2, "!"));
    no(new AlterDB("!", NAME2));
  }

  /** Command test. */
  @Test
  public final void alterUser() {
    ok(new CreateUser(NAME2, md5(NAME2)));
    ok(new AlterUser(NAME2, md5("test")));
    no(new AlterUser(":", md5(NAME2)));
  }

  /** Command test. */
  @Test
  public final void close() {
    // close is successful, even if no database is opened
    ok(new Close());
    ok(new CreateDB(NAME, FILE));
    ok(new Close());
  }

  /** Create Backup Test. Using glob Syntax. */
  @Test
  public final void createBackup() {
    no(new CreateBackup(NAME));
    ok(new CreateDB(NAME));
    ok(new CreateDB(NAME2));
    ok(new CreateBackup(NAME));
    ok(new Restore(NAME));
    ok(new Close());
    ok(new Restore(NAME));
    ok(new CreateBackup(NAME));
    ok(new Restore(NAME));
    ok(new DropBackup(NAME));
    ok(new CreateBackup(NAME + "*"));
    ok(new Restore(NAME2));
    ok(new DropBackup(NAME + "*"));
    no(new Restore(":"));
    ok(new CreateBackup(NAME + "?," + NAME));
    ok(new DropBackup(NAME2));
    ok(new Restore(NAME));
    no(new Restore(NAME + "?"));
    ok(new DropBackup(NAME));
  }

  /** Command test. */
  @Test
  public final void createDB() {
    ok(new CreateDB(NAME, FILE));
    ok(new InfoDB());
    ok(new CreateDB(NAME, FILE));
    ok(new CreateDB("abcde"));
    ok(new DropDB("abcde"));
    // invalid database names
    no(new CreateDB(""));
    no(new CreateDB(" "));
    no(new CreateDB(":"));
    no(new CreateDB("*?"));
    no(new CreateDB("/"));
  }

  /** Command test. */
  @Test
  public final void createIndex() {
    no(new CreateIndex(null));
    for (final CmdIndex cmd : CmdIndex.values()) no(new CreateIndex(cmd));
    ok(new CreateDB(NAME, FILE));
    for (final CmdIndex cmd : CmdIndex.values()) ok(new CreateIndex(cmd));
    no(new CreateIndex("x"));
  }

  /** Command test. */
  @Test
  public final void createUser() {
    ok(new CreateUser(NAME2, md5("test")));
    no(new CreateUser(NAME2, md5("test")));
    ok(new DropUser(NAME2));
    no(new CreateUser("", ""));
    no(new CreateUser(":", ""));
  }

  /** Command test. */
  @Test
  public final void cs() {
    no(new Cs("//li"));
    ok(new CreateDB(NAME, FILE));
    ok(new Cs("//  li"));
    ok(CONTEXT.current(), 2);
    ok(new Cs("."));
    ok(CONTEXT.current(), 2);
    ok(new Cs("/"));
    ok(CONTEXT.current(), 1);
  }

  /** Command test. */
  @Test
  public final void delete() {
    // database must be opened to add files
    no(new Delete(FILE));
    ok(new CreateDB(NAME));
    // target need not exist
    ok(new Delete(FILE));
    ok(new Add(FILE));
    ok(new Delete(FILE));
    ok(new Delete(FILE));
  }

  /** Command test. */
  @Test
  public final void dropDB() {
    ok(new DropDB(NAME));
    ok(new CreateDB(NAME, FILE));
    ok(new DropDB(NAME2));
    ok(new DropDB(NAME));
    ok(new DropDB(NAME));
    ok(new CreateDB(NAME));
    ok(new CreateDB(NAME2));
    ok(new DropDB(NAME + "*"));
    no(new Open(NAME2));
    no(new DropDB(":"));
    no(new DropDB(""));

    ok(new CreateDB(NAME));
    ok(new CreateDB(NAME2));
    ok(new DropDB(NAME + "," + NAME2));
    no(new DropDB(NAME + ", " + ":"));
  }

  /** Command test. */
  @Test
  public final void dropIndex() {
    for (final CmdIndex cmd : CmdIndex.values()) no(new DropIndex(cmd));
    ok(new CreateDB(NAME, FILE));
    for (final CmdIndex cmd : CmdIndex.values()) ok(new DropIndex(cmd));
    no(new DropIndex("x"));
  }

  /** Command test. */
  @Test
  public final void dropUser() {
    ok(new CreateUser(NAME, md5(NAME)));
    ok(new CreateUser(NAME2, md5(NAME)));

    ok(new DropUser(NAME));
    ok(new DropUser(NAME2));
    no(new DropUser(""));
    no(new DropUser(NAME2, ":"));

    ok(new CreateDB(NAME));
    ok(new CreateUser(NAME, md5(NAME)));
    ok(new CreateUser(NAME2, md5(NAME)));
    ok(new DropUser(NAME2, NAME + "*"));
    ok(new DropUser(NAME + "," + NAME2));
  }

  /** Command test. */
  @Test
  public final void export() {
    final IOFile io = new IOFile(FN);
    no(new Export(io.path()));
    ok(new CreateDB(NAME, FILE));
    ok(new Export("."));
    ok(io.exists());
    ok(io.delete());
  }

  /** Command test. */
  @Test
  public final void find() {
    no(new Find("1"));
    ok(new CreateDB(NAME, FILE));
    ok(new Find("1"));
  }

  /** Command test. */
  @Test
  public final void flush() {
    no(new Flush());
    ok(new CreateDB(NAME));
    ok(new Flush());
    ok(new Close());
    no(new Flush());
  }

  /** Command test. */
  @Test
  public final void get() {
    ok(new Get(CmdSet.CHOP));
    no(new Get(NAME2));
  }

  /** Command test. */
  @Test
  public final void grant() {
    ok(new CreateUser(NAME2, md5("test")));
    ok(new CreateUser(NAME, md5("test")));
    no(new Grant("something", NAME2));
    ok(new CreateDB(NAME));
    ok(new Grant("none", NAME + "*", NAME + "*"));
    no(new Grant("all", NAME2));
    no(new Grant("all", ":*?", ":*:"));
    ok(new DropUser(NAME + "," + NAME2));
    no(new Grant("all", NAME));
    no(new Grant("all", NAME + "*", ":"));
  }

  /** Command test. */
  @Test
  public final void help() {
    no(new Help("bla"));
    ok(new Help(null));
  }

  /** Command test. */
  @Test
  public final void info() {
    ok(new Info());
  }

  /** Command test. */
  @Test
  public final void infoDB() {
    no(new InfoDB());
    ok(new CreateDB(NAME, FILE));
    ok(new InfoDB());
  }

  /** Command test. */
  @Test
  public final void infoIndex() {
    no(new InfoIndex());
    ok(new CreateDB(NAME, FILE));
    ok(new InfoIndex());
    no(new InfoIndex("x"));
  }

  /** Command test. */
  @Test
  public final void infoTable() {
    no(new InfoStorage("1", "2"));
    ok(new CreateDB(NAME, FILE));
    ok(new InfoStorage("1", "2"));
    ok(new InfoStorage("1", null));
    ok(new InfoStorage("// li", null));
  }

  /** Command test. */
  @Test
  public final void list() {
    ok(new List());
    ok(new CreateDB(NAME, FILE));
    ok(new List());
  }

  /** Command test. */
  @Test
  public final void listdb() {
    no(new ListDB(NAME));
    ok(new CreateDB(NAME, FILE));
    ok(new ListDB(NAME));
  }

  /** Command test. */
  @Test
  public final void open() {
    no(new Open(NAME));
    ok(new CreateDB(NAME, FILE));
    ok(new Open(NAME));
    ok(new Open(NAME));
    no(new Open(":"));
  }

  /** Command test. */
  @Test
  public final void optimize() {
    no(new Optimize());
    no(new OptimizeAll());
    ok(new CreateDB(NAME, FILE));
    ok(new Optimize());
    ok(new OptimizeAll());
  }

  /** Command test. */
  @Test
  public final void password() {
    ok(new Password(md5(Text.ADMIN)));
    no(new Password(""));
  }

  /** Command test. */
  @Test
  public final void rename() {
    // database must be opened to rename paths
    no(new Rename(FILE, "xxx"));
    ok(new CreateDB(NAME, FILE));
    // target path must not be empty
    no(new Rename(FN, "/"));
    no(new Rename(FN, ""));
    ok(new Rename(FILE, FILE));
    ok(new Rename(FILE, "xxx"));
    // source need not exist
    ok(new Rename(FILE, "xxx"));
  }

  /** Command test. */
  @Test
  public final void replace() {
    // query to count number of documents
    final String count = "count(db:open('" + NAME + "'))";
    // database must be opened to replace resources
    no(new Replace(FILE, "xxx"));
    ok(new CreateDB(NAME, FILE));
    assertEquals("1", ok(new XQuery(count)));
    // replace existing document
    ok(new Replace(FN, "<a/>"));
    assertEquals("1", ok(new XQuery(count)));
    // replace existing document (again)
    ok(new Replace(FN, "<a/>"));
    assertEquals("1", ok(new XQuery(count)));
    // invalid content
    no(new Replace(FN, ""));
    assertEquals("1", ok(new XQuery(count)));
    // create and replace binary file
    ok(new XQuery("db:store('" + NAME + "', 'a', 'a')"));
    ok(new Replace("a", "<b/>"));
    assertTrue(ok(new XQuery("db:open('" + NAME + "')")).length() != 0);
    ok(new XQuery("db:retrieve('" + NAME + "', 'a')"));
    // a failing replace should not remove existing documents
    no(new Replace(FN, "<a>"));
    assertEquals("1", ok(new XQuery(count)));
  }

  /** Command test. */
  @Test
  public final void restore() {
    no(new Restore(NAME));
    ok(new CreateDB(NAME));
    ok(new CreateBackup(NAME));
    ok(new Restore(NAME));
    no(new Restore(":"));
    ok(new DropBackup(NAME));
    no(new Restore(NAME));
    ok(new Open(NAME));
    no(new Restore(NAME));
    ok(new XQuery("."));
    ok(new CreateDB("test-1"));
    ok(new CreateBackup("test-1"));
    ok(new Restore("test-1"));
    ok(new DropBackup("test"));
    no(new Restore("test"));
    ok(new DropBackup("test-1"));
    ok(new DropDB("test-1"));
    ok(new Close());
  }

  /** Retrieves raw data. */
  @Test
  public final void retrieve() {
    ok(new CreateDB(NAME));
    // retrieve non-existing file
    no(new Retrieve(NAME2));
    // retrieve existing file
    ok(new Store(NAME2, FILE));
    ok(new Retrieve(NAME2));
  }

  /** Stores raw data. */
  @Test
  public final void store() {
    ok(new CreateDB(NAME));
    ok(new Store(NAME2, FILE));
    // file can be overwritten
    ok(new Store(NAME2, FILE));
    // reject invalid names
    no(new Store("", FILE));
    no(new Store("../x", FILE));
  }

  /** Command test. */
  @Test
  public final void run() {
    final IOFile io = new IOFile("test.xq");
    no(new Run(io.path()));
    try {
      io.write(token("// li"));
    } catch (final Exception ex) {
      fail(Util.message(ex));
    }
    no(new Run(io.path()));
    ok(new CreateDB(NAME, FILE));
    ok(new Run(io.path()));
    io.delete();
  }

  /** Command test. */
  @Test
  public final void set() {
    ok(new Set(CmdSet.CHOP, false));
    ok(new Set(CmdSet.CHOP, true));
    ok(new Set("chop", true));
    ok(new Set("runs", 1));
    no(new Set("runs", true));
    no(new Set(NAME2, NAME2));
  }

  /** Command test. */
  @Test
  public final void showUsers() {
    ok(new ShowUsers());
    no(new ShowUsers(NAME));
    ok(new CreateDB(NAME));
    ok(new ShowUsers(NAME));
    no(new ShowUsers(":"));
  }

  /** Command test. */
  @Test
  public final void xquery() {
    no(new XQuery("/"));
    ok(new CreateDB(NAME, FILE));
    ok(new XQuery("/"));
    ok(new XQuery("1"));
    no(new XQuery("1+"));
  }

  /**
   * Assumes that the specified flag is successful.
   *
   * @param flag flag
   */
  private static void ok(final boolean flag) {
    assertTrue(flag);
  }

  /**
   * Assumes that the nodes have the specified number of nodes.
   *
   * @param nodes context nodes
   * @param size expected size
   */
  private static void ok(final Nodes nodes, final int size) {
    if (nodes != null) assertEquals(size, nodes.size());
  }

  /**
   * Assumes that this command is successful.
   *
   * @param cmd command reference
   * @return result as string
   */
  protected final String ok(final Command cmd) {
    try {
      return session.execute(cmd);
    } catch (final IOException ex) {
      fail(Util.message(ex));
      return null;
    }
  }

  /**
   * Assumes that this command fails.
   *
   * @param cmd command reference
   */
  protected final void no(final Command cmd) {
    try {
      session.execute(cmd);
      fail("\"" + cmd + "\" was supposed to fail.");
    } catch (final IOException ex) {
    }
  }
}
Esempio n. 9
0
 /**
  * Generates a stop file for the specified port.
  *
  * @param port server port
  * @return stop file
  */
 private static File stopFile(final int port) {
   return new File(Prop.TMP, Util.name(BaseXServer.class) + port);
 }
Esempio n. 10
0
 @Override
 public String toString() {
   return Util.name(this) + "[" + targetNode() + "]";
 }