aboutsummaryrefslogtreecommitdiffstats
path: root/document/src
diff options
context:
space:
mode:
Diffstat (limited to 'document/src')
-rw-r--r--document/src/main/java/com/yahoo/document/DocumentUpdate.java10
-rw-r--r--document/src/main/java/com/yahoo/document/datatypes/StringFieldValue.java14
-rw-r--r--document/src/main/java/com/yahoo/document/json/JsonSerializationHelper.java1
-rw-r--r--document/src/main/java/com/yahoo/document/json/JsonWriter.java22
-rw-r--r--document/src/main/java/com/yahoo/document/serialization/DocumentUpdateWriter.java3
-rw-r--r--document/src/main/java/com/yahoo/document/serialization/DocumentWriter.java6
-rw-r--r--document/src/main/java/com/yahoo/document/serialization/VespaDocumentSerializer6.java5
-rw-r--r--document/src/tests/serialization/CMakeLists.txt1
-rw-r--r--document/src/tests/serialization/annotationserializer_test.cpp137
-rw-r--r--document/src/tests/struct_anno/CMakeLists.txt1
-rw-r--r--document/src/tests/struct_anno/struct_anno_test.cpp34
-rw-r--r--document/src/vespa/document/select/branch.cpp10
12 files changed, 132 insertions, 112 deletions
diff --git a/document/src/main/java/com/yahoo/document/DocumentUpdate.java b/document/src/main/java/com/yahoo/document/DocumentUpdate.java
index d3063b76feb..20d9b352d2d 100644
--- a/document/src/main/java/com/yahoo/document/DocumentUpdate.java
+++ b/document/src/main/java/com/yahoo/document/DocumentUpdate.java
@@ -147,7 +147,7 @@ public class DocumentUpdate extends DocumentOperation implements Iterable<FieldP
Map.Entry<Integer, FieldUpdate> entry = iter.next();
FieldUpdate update = entry.getValue();
if (!update.isEmpty()) {
- ValueUpdate last = update.getValueUpdate(update.size() - 1);
+ ValueUpdate<?> last = update.getValueUpdate(update.size() - 1);
if (last instanceof AssignValueUpdate) {
FieldValue currentValue = doc.getFieldValue(update.getField());
if ((currentValue != null) && currentValue.equals(last.getValue())) {
@@ -190,7 +190,7 @@ public class DocumentUpdate extends DocumentOperation implements Iterable<FieldP
/** Returns the type of the document this updates
*
- * @return The documentype of the document
+ * @return The document type of the document
*/
public DocumentType getDocumentType() {
return documentType;
@@ -357,9 +357,7 @@ public class DocumentUpdate extends DocumentOperation implements Iterable<FieldP
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof DocumentUpdate)) return false;
-
- DocumentUpdate that = (DocumentUpdate) o;
+ if (!(o instanceof DocumentUpdate that)) return false;
if (docId != null ? !docId.equals(that.docId) : that.docId != null) return false;
if (documentType != null ? !documentType.equals(that.documentType) : that.documentType != null) return false;
@@ -413,7 +411,7 @@ public class DocumentUpdate extends DocumentOperation implements Iterable<FieldP
}
/**
- * Returns whether or not this field update contains any field- or field path updates.
+ * Returns whether this field update contains any field- or field path updates.
*
* @return True if this update is empty.
*/
diff --git a/document/src/main/java/com/yahoo/document/datatypes/StringFieldValue.java b/document/src/main/java/com/yahoo/document/datatypes/StringFieldValue.java
index 8b4b94f6bbf..d09967f973f 100644
--- a/document/src/main/java/com/yahoo/document/datatypes/StringFieldValue.java
+++ b/document/src/main/java/com/yahoo/document/datatypes/StringFieldValue.java
@@ -29,6 +29,9 @@ import java.util.Objects;
*/
public class StringFieldValue extends FieldValue {
+ // TODO: remove this, it's a temporary workaround for invalid data stored before unicode validation was fixed
+ private static final boolean replaceInvalidUnicode = System.getProperty("vespa.replace_invalid_unicode", "false").equals("true");
+
private static class Factory extends PrimitiveDataType.Factory {
@Override public FieldValue create() { return new StringFieldValue(); }
@Override public FieldValue create(String value) { return new StringFieldValue(value); }
@@ -56,16 +59,17 @@ public class StringFieldValue extends FieldValue {
setValue(value);
}
- private static void validateTextString(String value) {
+ private static String validateTextString(String value) {
if ( ! Text.isValidTextString(value)) {
- throw new IllegalArgumentException("The string field value contains illegal code point 0x" +
- Integer.toHexString(Text.validateTextString(value).getAsInt()).toUpperCase());
+ if (replaceInvalidUnicode) return Text.stripInvalidCharacters(value);
+ else throw new IllegalArgumentException("The string field value contains illegal code point 0x" +
+ Integer.toHexString(Text.validateTextString(value).getAsInt()).toUpperCase());
}
+ return value;
}
private void setValue(String value) {
- validateTextString(value);
- this.value = value;
+ this.value = validateTextString(value);
}
/**
diff --git a/document/src/main/java/com/yahoo/document/json/JsonSerializationHelper.java b/document/src/main/java/com/yahoo/document/json/JsonSerializationHelper.java
index 7b1042903ec..ed6bdc721a0 100644
--- a/document/src/main/java/com/yahoo/document/json/JsonSerializationHelper.java
+++ b/document/src/main/java/com/yahoo/document/json/JsonSerializationHelper.java
@@ -347,4 +347,5 @@ public class JsonSerializationHelper {
wrapIOException(() -> generator.writeFieldName(field.getName()));
}
}
+
}
diff --git a/document/src/main/java/com/yahoo/document/json/JsonWriter.java b/document/src/main/java/com/yahoo/document/json/JsonWriter.java
index 7e82e830064..2b0ba138466 100644
--- a/document/src/main/java/com/yahoo/document/json/JsonWriter.java
+++ b/document/src/main/java/com/yahoo/document/json/JsonWriter.java
@@ -7,7 +7,9 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.yahoo.document.Document;
import com.yahoo.document.DocumentId;
+import com.yahoo.document.DocumentRemove;
import com.yahoo.document.DocumentType;
+import com.yahoo.document.DocumentUpdate;
import com.yahoo.document.Field;
import com.yahoo.document.annotation.AnnotationReference;
import com.yahoo.document.datatypes.Array;
@@ -263,6 +265,26 @@ public class JsonWriter implements DocumentWriter {
// NOP, fetched from Document
}
+ @Override
+ public void write(DocumentRemove documentRemove) {
+ try {
+ generator.writeStartObject();
+
+ serializeStringField(generator, new FieldBase("remove"), new StringFieldValue(documentRemove.getId().toString()));
+
+ generator.writeEndObject();
+ generator.flush();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void write(DocumentUpdate documentUpdate) {
+ var serializer = new DocumentUpdateJsonSerializer(generator);
+ serializer.serialize(documentUpdate);
+ }
+
/**
* Utility method to easily serialize a single document.
*
diff --git a/document/src/main/java/com/yahoo/document/serialization/DocumentUpdateWriter.java b/document/src/main/java/com/yahoo/document/serialization/DocumentUpdateWriter.java
index 0202ec8bf23..b9cc439ad54 100644
--- a/document/src/main/java/com/yahoo/document/serialization/DocumentUpdateWriter.java
+++ b/document/src/main/java/com/yahoo/document/serialization/DocumentUpdateWriter.java
@@ -17,8 +17,7 @@ import com.yahoo.document.update.TensorRemoveUpdate;
/**
* Interface for writing document updates in custom serializers.
*
- * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
- * @since 5.1.27
+ * @author Einar M R Rosenvinge
*/
public interface DocumentUpdateWriter {
void write(DocumentUpdate update);
diff --git a/document/src/main/java/com/yahoo/document/serialization/DocumentWriter.java b/document/src/main/java/com/yahoo/document/serialization/DocumentWriter.java
index c84140c9ea0..16125926fe6 100644
--- a/document/src/main/java/com/yahoo/document/serialization/DocumentWriter.java
+++ b/document/src/main/java/com/yahoo/document/serialization/DocumentWriter.java
@@ -3,7 +3,9 @@ package com.yahoo.document.serialization;
import com.yahoo.document.Document;
import com.yahoo.document.DocumentId;
+import com.yahoo.document.DocumentRemove;
import com.yahoo.document.DocumentType;
+import com.yahoo.document.DocumentUpdate;
/**
* @author ravishar
@@ -17,4 +19,8 @@ public interface DocumentWriter extends FieldWriter {
void write(DocumentType type);
+ void write(DocumentRemove documentRemove);
+
+ void write(DocumentUpdate documentUpdate);
+
}
diff --git a/document/src/main/java/com/yahoo/document/serialization/VespaDocumentSerializer6.java b/document/src/main/java/com/yahoo/document/serialization/VespaDocumentSerializer6.java
index 17ab3890bcf..4cb836860be 100644
--- a/document/src/main/java/com/yahoo/document/serialization/VespaDocumentSerializer6.java
+++ b/document/src/main/java/com/yahoo/document/serialization/VespaDocumentSerializer6.java
@@ -8,6 +8,7 @@ import com.yahoo.document.CollectionDataType;
import com.yahoo.document.DataType;
import com.yahoo.document.Document;
import com.yahoo.document.DocumentId;
+import com.yahoo.document.DocumentRemove;
import com.yahoo.document.DocumentType;
import com.yahoo.document.DocumentUpdate;
import com.yahoo.document.Field;
@@ -426,6 +427,10 @@ public class VespaDocumentSerializer6 extends BufferSerializer implements Docume
putShort(null, (short) 0); // Used to hold the version. Is now always 0.
}
+ public void write(DocumentRemove documentRemove) {
+ throw new UnsupportedOperationException("serializing remove not implemented");
+ }
+
public void write(Annotation annotation) {
buf.putInt(annotation.getType().getId()); //name hash
diff --git a/document/src/tests/serialization/CMakeLists.txt b/document/src/tests/serialization/CMakeLists.txt
index e5bf91f401d..8a997299e38 100644
--- a/document/src/tests/serialization/CMakeLists.txt
+++ b/document/src/tests/serialization/CMakeLists.txt
@@ -11,5 +11,6 @@ vespa_add_executable(document_annotationserializer_test_app TEST
annotationserializer_test.cpp
DEPENDS
document
+ GTest::gtest
)
vespa_add_test(NAME document_annotationserializer_test_app COMMAND document_annotationserializer_test_app)
diff --git a/document/src/tests/serialization/annotationserializer_test.cpp b/document/src/tests/serialization/annotationserializer_test.cpp
index 14edd38d0b0..3499f9d8012 100644
--- a/document/src/tests/serialization/annotationserializer_test.cpp
+++ b/document/src/tests/serialization/annotationserializer_test.cpp
@@ -11,11 +11,13 @@
#include <vespa/document/serialization/vespadocumentdeserializer.h>
#include <vespa/document/serialization/vespadocumentserializer.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/vespalib/gtest/gtest.h>
#include <vespa/vespalib/objects/nbostream.h>
-#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/vespalib/testkit/test_path.h>
#include <vespa/fastos/file.h>
-#include <fstream>
#include <algorithm>
+#include <fstream>
+#include <optional>
using std::fstream;
@@ -27,35 +29,11 @@ using namespace document;
namespace {
-class Test : public vespalib::TestApp {
- StringFieldValue::SpanTrees readSpanTree(const string &file_name, const FixedTypeRepo &repo);
-
- void requireThatSimpleSpanTreeIsDeserialized();
- void requireThatAdvancedSpanTreeIsDeserialized();
- void requireThatSpanTreeCanBeSerialized();
- void requireThatUnknownAnnotationIsSkipped();
-
-public:
- int Main() override;
-};
-
-int
-Test::Main()
-{
- if (getenv("TEST_SUBSET") != 0) { return 0; }
- TEST_INIT("annotationserializer_test");
- TEST_DO(requireThatSimpleSpanTreeIsDeserialized());
- TEST_DO(requireThatAdvancedSpanTreeIsDeserialized());
- TEST_DO(requireThatSpanTreeCanBeSerialized());
- TEST_DO(requireThatUnknownAnnotationIsSkipped());
-
- TEST_DONE();
-}
-
template <typename T, int N> int arraysize(const T (&)[N]) { return N; }
-StringFieldValue::SpanTrees
-Test::readSpanTree(const string &file_name, const FixedTypeRepo &repo) {
+void
+read_span_trees(const string &file_name, const FixedTypeRepo &repo, std::optional<StringFieldValue::SpanTrees>& span_trees)
+{
FastOS_File file(file_name.c_str());
ASSERT_TRUE(file.OpenReadOnlyExisting());
char buffer[1024];
@@ -67,26 +45,31 @@ Test::readSpanTree(const string &file_name, const FixedTypeRepo &repo) {
StringFieldValue value;
deserializer.read(value);
- EXPECT_EQUAL(0u, stream.size());
+ EXPECT_EQ(0u, stream.size());
ASSERT_TRUE(value.hasSpanTrees());
- return value.getSpanTrees();
+ span_trees = value.getSpanTrees();
}
-void Test::requireThatSimpleSpanTreeIsDeserialized() {
+}
+
+TEST(AnnotationSerializerTest, require_that_simple_span_tree_is_deserialized)
+{
DocumentTypeRepo type_repo(readDocumenttypesConfig(TEST_PATH("annotation.serialize.test.repo.cfg")));
FixedTypeRepo repo(type_repo);
- SpanTree::UP span_tree = std::move(readSpanTree(TEST_PATH("test_data_serialized_simple"), repo).front());
+ std::optional<StringFieldValue::SpanTrees> span_trees;
+ ASSERT_NO_FATAL_FAILURE(read_span_trees(TEST_PATH("test_data_serialized_simple"), repo, span_trees));
+ auto span_tree = std::move(span_trees.value().front());
- EXPECT_EQUAL("html", span_tree->getName());
+ EXPECT_EQ("html", span_tree->getName());
const SimpleSpanList *root = dynamic_cast<const SimpleSpanList *>(&span_tree->getRoot());
ASSERT_TRUE(root);
- EXPECT_EQUAL(5u, root->size());
+ EXPECT_EQ(5u, root->size());
SimpleSpanList::const_iterator it = root->begin();
- EXPECT_EQUAL(Span(0, 19), (*it++));
- EXPECT_EQUAL(Span(19, 5), (*it++));
- EXPECT_EQUAL(Span(24, 21), (*it++));
- EXPECT_EQUAL(Span(45, 23), (*it++));
- EXPECT_EQUAL(Span(68, 14), (*it++));
+ EXPECT_EQ(Span(0, 19), (*it++));
+ EXPECT_EQ(Span(19, 5), (*it++));
+ EXPECT_EQ(Span(24, 21), (*it++));
+ EXPECT_EQ(Span(45, 23), (*it++));
+ EXPECT_EQ(Span(68, 14), (*it++));
EXPECT_TRUE(it == root->end());
}
@@ -107,49 +90,51 @@ struct AnnotationComparator {
void compare() {
std::sort(expect.begin(), expect.end());
std::sort(actual.begin(), actual.end());
- EXPECT_EQUAL(expect.size(), actual.size());
+ EXPECT_EQ(expect.size(), actual.size());
for (size_t i = 0; i < expect.size() && i < actual.size(); ++i) {
- EXPECT_EQUAL(expect[i].size(), actual[i].size());
- EXPECT_EQUAL(expect[i], actual[i]);
+ EXPECT_EQ(expect[i].size(), actual[i].size());
+ EXPECT_EQ(expect[i], actual[i]);
}
}
};
-void Test::requireThatAdvancedSpanTreeIsDeserialized() {
+TEST(AnnotationSerializerTest, require_that_advanced_span_tree_is_deserialized)
+{
DocumentTypeRepo type_repo(readDocumenttypesConfig(TEST_PATH("annotation.serialize.test.repo.cfg")));
FixedTypeRepo repo(type_repo, "my_document");
- SpanTree::UP span_tree = std::move(readSpanTree(TEST_PATH("test_data_serialized_advanced"),
- repo).front());
+ std::optional<StringFieldValue::SpanTrees> span_trees;
+ ASSERT_NO_FATAL_FAILURE(read_span_trees(TEST_PATH("test_data_serialized_advanced"), repo, span_trees));
+ auto span_tree = std::move(span_trees.value().front());
- EXPECT_EQUAL("html", span_tree->getName());
+ EXPECT_EQ("html", span_tree->getName());
const SpanList *root = dynamic_cast<const SpanList *>(&span_tree->getRoot());
ASSERT_TRUE(root);
- EXPECT_EQUAL(4u, root->size());
+ EXPECT_EQ(4u, root->size());
SpanList::const_iterator it = root->begin();
- EXPECT_EQUAL(Span(0, 6), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(0, 6), *(static_cast<Span *>(*it++)));
AlternateSpanList *alt_list = dynamic_cast<AlternateSpanList *>(*it++);
- EXPECT_EQUAL(Span(27, 9), *(static_cast<Span *>(*it++)));
- EXPECT_EQUAL(Span(36, 8), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(27, 9), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(36, 8), *(static_cast<Span *>(*it++)));
EXPECT_TRUE(it == root->end());
ASSERT_TRUE(alt_list);
- EXPECT_EQUAL(2u, alt_list->getNumSubtrees());
- EXPECT_EQUAL(0.9, alt_list->getProbability(0));
- EXPECT_EQUAL(0.1, alt_list->getProbability(1));
- EXPECT_EQUAL(4u, alt_list->getSubtree(0).size());
+ EXPECT_EQ(2u, alt_list->getNumSubtrees());
+ EXPECT_EQ(0.9, alt_list->getProbability(0));
+ EXPECT_EQ(0.1, alt_list->getProbability(1));
+ EXPECT_EQ(4u, alt_list->getSubtree(0).size());
it = alt_list->getSubtree(0).begin();
- EXPECT_EQUAL(Span(6, 3), *(static_cast<Span *>(*it++)));
- EXPECT_EQUAL(Span(9, 10), *(static_cast<Span *>(*it++)));
- EXPECT_EQUAL(Span(19, 4), *(static_cast<Span *>(*it++)));
- EXPECT_EQUAL(Span(23, 4), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(6, 3), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(9, 10), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(19, 4), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(23, 4), *(static_cast<Span *>(*it++)));
EXPECT_TRUE(it == alt_list->getSubtree(0).end());
- EXPECT_EQUAL(2u, alt_list->getSubtree(1).size());
+ EXPECT_EQ(2u, alt_list->getSubtree(1).size());
it = alt_list->getSubtree(1).begin();
- EXPECT_EQUAL(Span(6, 13), *(static_cast<Span *>(*it++)));
- EXPECT_EQUAL(Span(19, 8), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(6, 13), *(static_cast<Span *>(*it++)));
+ EXPECT_EQ(Span(19, 8), *(static_cast<Span *>(*it++)));
EXPECT_TRUE(it == alt_list->getSubtree(1).end());
- EXPECT_EQUAL(12u, span_tree->numAnnotations());
+ EXPECT_EQ(12u, span_tree->numAnnotations());
AnnotationComparator comparator;
comparator.addActual(span_tree->begin(), span_tree->end())
@@ -213,10 +198,11 @@ void Test::requireThatAdvancedSpanTreeIsDeserialized() {
" AnnotationReferenceFieldValue(n)\n"
" )\n"
"))");
- TEST_DO(comparator.compare());
+ comparator.compare();
}
-void Test::requireThatSpanTreeCanBeSerialized() {
+TEST(AnnotationSerializerTest, require_that_span_tree_can_be_serialized)
+{
DocumentTypeRepo type_repo(
readDocumenttypesConfig(TEST_PATH("annotation.serialize.test.repo.cfg")));
FixedTypeRepo repo(type_repo, "my_document");
@@ -233,25 +219,26 @@ void Test::requireThatSpanTreeCanBeSerialized() {
StringFieldValue value;
deserializer.read(value);
- SpanTree::UP span_tree = std::move(value.getSpanTrees().front());
- EXPECT_EQUAL("html", span_tree->getName());
- EXPECT_EQUAL(0u, stream.size());
+ auto span_tree = std::move(value.getSpanTrees().front());
+ EXPECT_EQ("html", span_tree->getName());
+ EXPECT_EQ(0u, stream.size());
stream.clear();
VespaDocumentSerializer serializer(stream);
serializer.write(value);
- EXPECT_EQUAL(size, static_cast<ssize_t>(stream.size()));
+ EXPECT_EQ(size, static_cast<ssize_t>(stream.size()));
int diff_count = 0;
for (size_t i = 0; i < stream.size(); ++i) {
if (buffer[i] != stream.peek()[i]) {
++diff_count;
}
- EXPECT_EQUAL((int) buffer[i], (int) stream.peek()[i]);
+ EXPECT_EQ((int) buffer[i], (int) stream.peek()[i]);
}
- EXPECT_EQUAL(0, diff_count);
+ EXPECT_EQ(0, diff_count);
}
-void Test::requireThatUnknownAnnotationIsSkipped() {
+TEST(AnnotationSerializerTest, require_that_unknown_annotation_is_skipped)
+{
AnnotationType type(42, "my type");
Annotation annotation(type, FieldValue::UP(new StringFieldValue("foo")));
nbostream stream;
@@ -264,9 +251,7 @@ void Test::requireThatUnknownAnnotationIsSkipped() {
Annotation a;
deserializer.readAnnotation(a);
EXPECT_FALSE(a.valid());
- EXPECT_EQUAL(0u, stream.size());
+ EXPECT_EQ(0u, stream.size());
}
-} // namespace
-
-TEST_APPHOOK(Test);
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/document/src/tests/struct_anno/CMakeLists.txt b/document/src/tests/struct_anno/CMakeLists.txt
index 855cba606a3..2d688454058 100644
--- a/document/src/tests/struct_anno/CMakeLists.txt
+++ b/document/src/tests/struct_anno/CMakeLists.txt
@@ -4,5 +4,6 @@ vespa_add_executable(document_struct_anno_test_app TEST
struct_anno_test.cpp
DEPENDS
document
+ GTest::gtest
)
vespa_add_test(NAME document_struct_anno_test_app COMMAND document_struct_anno_test_app)
diff --git a/document/src/tests/struct_anno/struct_anno_test.cpp b/document/src/tests/struct_anno/struct_anno_test.cpp
index 31d3900c6bc..8ab883c6de1 100644
--- a/document/src/tests/struct_anno/struct_anno_test.cpp
+++ b/document/src/tests/struct_anno/struct_anno_test.cpp
@@ -11,8 +11,9 @@
#include <vespa/document/serialization/vespadocumentdeserializer.h>
#include <vespa/document/serialization/vespadocumentserializer.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/vespalib/gtest/gtest.h>
#include <vespa/vespalib/objects/nbostream.h>
-#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/vespalib/testkit/test_path.h>
#include <vespa/fastos/file.h>
using std::ostringstream;
@@ -23,23 +24,12 @@ using namespace document;
namespace {
-class Test : public vespalib::TestApp {
- void requireThatStructFieldsCanContainAnnotations();
-
-public:
- int Main() override;
-};
+template <typename T, int N> int arraysize(const T (&)[N]) { return N; }
-int Test::Main() {
- if (getenv("TEST_SUBSET") != 0) { return 0; }
- TEST_INIT("struct_anno_test");
- TEST_DO(requireThatStructFieldsCanContainAnnotations());
- TEST_DONE();
}
-template <typename T, int N> int arraysize(const T (&)[N]) { return N; }
-
-void Test::requireThatStructFieldsCanContainAnnotations() {
+TEST(StructAnnoTest, require_that_struct_fields_can_contain_annotations)
+{
DocumentTypeRepo repo(readDocumenttypesConfig(TEST_PATH("documenttypes.cfg")));
FastOS_File file(TEST_PATH("document.dat").c_str());
@@ -62,19 +52,17 @@ void Test::requireThatStructFieldsCanContainAnnotations() {
const StringFieldValue *str = dynamic_cast<const StringFieldValue*>(strRef.get());
ASSERT_TRUE(str != NULL);
- SpanTree::UP tree = std::move(str->getSpanTrees().front());
+ auto tree = std::move(str->getSpanTrees().front());
- EXPECT_EQUAL("my_tree", tree->getName());
+ EXPECT_EQ("my_tree", tree->getName());
const SimpleSpanList *root = dynamic_cast<const SimpleSpanList*>(&tree->getRoot());
ASSERT_TRUE(root != NULL);
- EXPECT_EQUAL(1u, root->size());
+ EXPECT_EQ(1u, root->size());
SimpleSpanList::const_iterator it = root->begin();
- EXPECT_EQUAL(Span(0, 6), (*it++));
+ EXPECT_EQ(Span(0, 6), (*it++));
EXPECT_TRUE(it == root->end());
- EXPECT_EQUAL(1u, tree->numAnnotations());
+ EXPECT_EQ(1u, tree->numAnnotations());
}
-} // namespace
-
-TEST_APPHOOK(Test);
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/document/src/vespa/document/select/branch.cpp b/document/src/vespa/document/select/branch.cpp
index 02f767c96b5..6035b5fe9a0 100644
--- a/document/src/vespa/document/select/branch.cpp
+++ b/document/src/vespa/document/select/branch.cpp
@@ -39,6 +39,10 @@ namespace {
ResultList traceAndValue(const T& value, std::ostream& out,
const Node& leftNode, const Node& rightNode)
{
+ out << "And (lhs):\n";
+ (void)leftNode.trace(value, out);
+ out << "And (rhs):\n";
+ (void)rightNode.trace(value, out);
out << "And - Left branch returned " << leftNode.contains(value) << ".\n";
out << "And - Right branch returned " << rightNode.contains(value) << ".\n";
return leftNode.contains(value) && rightNode.contains(value);
@@ -83,6 +87,10 @@ namespace {
ResultList traceOrValue(const T& value, std::ostream& out,
const Node& leftNode, const Node& rightNode)
{
+ out << "Or (lhs):\n";
+ (void)leftNode.trace(value, out);
+ out << "Or (rhs):\n";
+ (void)rightNode.trace(value, out);
out << "Or - Left branch returned " << leftNode.contains(value) << ".\n";
out << "Or - Right branch returned " << rightNode.contains(value) << ".\n";
return leftNode.contains(value) || rightNode.contains(value);
@@ -122,6 +130,8 @@ namespace {
template<typename T>
ResultList traceNotValue(const T& value, std::ostream& out, const Node& node)
{
+ out << "Not:\n";
+ (void)node.trace(value, out);
out << "Not - Child returned " << node.contains(value)
<< ". Returning opposite.\n";
return !node.contains(value);