1
0
Fork 0

Fixed minor inconsistency in AQL NEIGHBORS and adapted tests to the new version. It will now Return the list of vertices. not the pair<edge, vertex> any more

This commit is contained in:
Michael Hackstein 2015-05-22 15:30:24 -07:00
parent e1813327b5
commit 0b8e9eb59c
5 changed files with 216 additions and 204 deletions

View File

@ -381,86 +381,51 @@ unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
}
vector<VertexId> TRI_RunNeighborsSearch (
v8::Isolate* isolate,
TRI_vocbase_t* vocbase,
std::string const& vertexCollectionName,
std::string const& edgeCollectionName,
std::string const& startVertex,
CollectionNameResolver const* resolver,
TRI_document_collection_t* ecol,
vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts
) {
// Transform string ids to VertexIds
// Needs refactoring!
size_t split;
char const* str = startVertex.c_str();
vector<VertexId> result;
if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) {
// TODO Error Handling
return result;
}
string collectionName = startVertex.substr(0, split);
auto coli = resolver->getCollectionStruct(collectionName);
if (coli == nullptr) {
// collection not found
throw TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
if (opts.distinct) {
unordered_set<VertexId> distinct;
if (opts.direction == "any") {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
if (opts.direction == TRI_EDGE_IN || opts.direction == TRI_EDGE_ANY) {
TRI_edge_direction_e dir = TRI_EDGE_IN;
for (auto col : collectionInfos) {
auto edges = col->getEdges(dir, opts.start);
for (size_t j = 0; j < edges.size(); ++j) {
distinct.insert(extractFromId(edges[j]));
}
edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
}
}
if (opts.direction == TRI_EDGE_OUT || opts.direction == TRI_EDGE_ANY) {
TRI_edge_direction_e dir = TRI_EDGE_OUT;
for (auto col : collectionInfos) {
auto edges = col->getEdges(dir, opts.start);
for (size_t j = 0; j < edges.size(); ++j) {
distinct.insert(extractToId(edges[j]));
}
} else if (opts.direction == "inbound") {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
for (size_t j = 0; j < edges.size(); ++j) {
distinct.insert(extractFromId(edges[j]));
}
} else {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
for (size_t j = 0; j < edges.size(); ++j) {
distinct.insert(extractToId(edges[j]));
}
}
copy(distinct.begin(), distinct.end(), back_inserter(result));
} else {
if (opts.direction == "any") {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
if (opts.direction == TRI_EDGE_IN || opts.direction == TRI_EDGE_ANY) {
TRI_edge_direction_e dir = TRI_EDGE_IN;
for (auto col : collectionInfos) {
auto edges = col->getEdges(dir, opts.start);
for (size_t j = 0; j < edges.size(); ++j) {
result.push_back(extractFromId(edges[j]));
}
edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
for (size_t j = 0; j < edges.size(); ++j) {
result.push_back(extractToId(edges[j]));
}
} else if (opts.direction == "inbound") {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_IN, coli->_cid, const_cast<char*>(str + split + 1));
for (size_t j = 0; j < edges.size(); ++j) {
result.push_back(extractFromId(edges[j]));
}
} else {
auto edges = TRI_LookupEdgesDocumentCollection(ecol,
TRI_EDGE_OUT, coli->_cid, const_cast<char*>(str + split + 1));
if (opts.direction == TRI_EDGE_OUT || opts.direction == TRI_EDGE_ANY) {
TRI_edge_direction_e dir = TRI_EDGE_OUT;
for (auto col : collectionInfos) {
auto edges = col->getEdges(dir, opts.start);
for (size_t j = 0; j < edges.size(); ++j) {
result.push_back(extractToId(edges[j]));
}
}
}
}
return result;
};

View File

@ -149,15 +149,16 @@ namespace triagens {
bool matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const;
bool matchesVertex (VertexId& v) const;
};
struct NeighborsOptions {
std::string direction;
TRI_edge_direction_e direction;
bool distinct;
VertexId start;
NeighborsOptions () :
direction("outbound"),
distinct(false) {
direction(TRI_EDGE_OUT),
distinct(true) {
}
};
@ -292,13 +293,7 @@ std::unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
////////////////////////////////////////////////////////////////////////////////
std::vector<VertexId> TRI_RunNeighborsSearch (
v8::Isolate* isolate,
TRI_vocbase_t* vocbase,
std::string const& vertexCollectionName,
std::string const& edgeCollectionName,
std::string const& startVertex,
triagens::arango::CollectionNameResolver const* resolver,
TRI_document_collection_t* ecol,
std::vector<EdgeCollectionInfo*>& collectionInfos,
triagens::basics::traverser::NeighborsOptions& opts
);

View File

@ -1669,7 +1669,7 @@ static ExplicitTransaction* beginTransaction(
// Abort the collection and free the pointers
trx->abort();
delete trx;
throw e;
throw;
}
return trx;
}
@ -1854,7 +1854,7 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
unordered_set<string> vertexCollectionNames;
v8ArrayToStrings(args[0], vertexCollectionNames);
// get the vertex collections
// get the edge collections
if (! args[1]->IsArray()) {
TRI_V8_THROW_TYPE_ERROR("expecting array for <edgecollections[]>");
}
@ -2033,8 +2033,15 @@ static void JS_QueryShortestPath (const v8::FunctionCallbackInfo<v8::Value>& arg
}
}
try {
opts.start = idStringToVertexId(resolver, startVertex);
opts.end = idStringToVertexId(resolver, targetVertex);
} catch (int e) {
// Id string might have illegal collection name
trx->finish(e);
delete trx;
TRI_V8_THROW_EXCEPTION(e);
}
try {
path = TRI_RunShortestPathSearch(
@ -2074,12 +2081,8 @@ static v8::Handle<v8::Value> vertexIdsToV8(v8::Isolate* isolate,
CollectionNameResolver const* resolver,
vector<VertexId>& ids,
unordered_map<TRI_voc_cid_t, CollectionBarrierInfo>& barriers,
bool includeData = false,
bool includeDuplicates = true) {
bool includeData = false) {
v8::EscapableHandleScope scope(isolate);
v8::Handle<v8::Object> result = v8::Object::New(isolate);
if (includeDuplicates) {
uint32_t const vn = static_cast<uint32_t>(ids.size());
v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));
@ -2092,36 +2095,13 @@ static v8::Handle<v8::Value> vertexIdsToV8(v8::Isolate* isolate,
vertices->Set(j, vertexIdToString(isolate, resolver, ids[j]));
}
}
result->Set(TRI_V8_STRING("vertices"), vertices);
return scope.Escape<v8::Value>(result);
} else {
// set<VertexId> uniqueIds(ids.begin(), ids.end());
// TODO
auto uniqueIds = ids;
uint32_t const vn = static_cast<uint32_t>(uniqueIds.size());
v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));
auto iterator = uniqueIds.begin();
if (includeData) {
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, vertexIdToData(isolate, resolver, trx, barriers, *iterator));
++iterator;
}
} else {
for (uint32_t j = 0; j < vn; ++j) {
vertices->Set(j, vertexIdToString(isolate, resolver, *iterator));
++iterator;
}
}
result->Set(TRI_V8_STRING("vertices"), vertices);
return scope.Escape<v8::Value>(result);
}
return scope.Escape<v8::Value>(vertices);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Executes a shortest Path Traversal
/// @brief Executes a Neighbors computation
////////////////////////////////////////////////////////////////////////////////
static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args) {
@ -2129,74 +2109,88 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
v8::HandleScope scope(isolate);
if (args.Length() < 3 || args.Length() > 4) {
TRI_V8_THROW_EXCEPTION_USAGE("CPP_NEIGHBORS(<vertexcollection>, <edgecollection>, <start>, <options>)");
TRI_V8_THROW_EXCEPTION_USAGE("CPP_NEIGHBORS(<vertexcollections[]>, <edgecollections[]>, <start>, <options>)");
}
TRI_vocbase_t* vocbase;
vocbase = GetContextVocBase(isolate);
// get the vertex collection
if (! args[0]->IsString()) {
TRI_V8_THROW_TYPE_ERROR("expecting string for <vertexcollection>");
// get the vertex collections
if (! args[0]->IsArray()) {
TRI_V8_THROW_TYPE_ERROR("expecting array for <vertexcollections[]>");
}
string vertexCollectionName = TRI_ObjectToString(args[0]);
unordered_set<string> vertexCollectionNames;
v8ArrayToStrings(args[0], vertexCollectionNames);
// get the edge collection
if (! args[1]->IsString()) {
TRI_V8_THROW_TYPE_ERROR("expecting string for <edgecollection>");
// get the edge collections
if (! args[1]->IsArray()) {
TRI_V8_THROW_TYPE_ERROR("expecting array for <edgecollections[]>");
}
string const edgeCollectionName = TRI_ObjectToString(args[1]);
unordered_set<string> edgeCollectionNames;
v8ArrayToStrings(args[1], edgeCollectionNames);
vocbase = GetContextVocBase(isolate);
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
if (vocbase == nullptr) {
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! args[2]->IsString()) {
TRI_V8_THROW_TYPE_ERROR("expecting string for <startVertex>");
TRI_V8_THROW_TYPE_ERROR("expecting id for <startVertex>");
}
string const startVertex = TRI_ObjectToString(args[2]);
// TODO Option parsing
traverser::NeighborsOptions opts;
bool includeData = false;
v8::Handle<v8::Object> vertexExample;
if (args.Length() == 4) {
if (! args[3]->IsObject()) {
TRI_V8_THROW_TYPE_ERROR("expecting json for <options>");
}
v8::Handle<v8::Object> options = args[3]->ToObject();
v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
v8::Local<v8::String> keyDistinct= TRI_V8_ASCII_STRING("distinct");
// Parse direction
v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
if (options->Has(keyDirection) ) {
opts.direction = TRI_ObjectToString(options->Get(keyDirection));
if ( opts.direction != "outbound"
&& opts.direction != "inbound"
&& opts.direction != "any"
) {
string dir = TRI_ObjectToString(options->Get(keyDirection));
if (dir == "outbound") {
opts.direction = TRI_EDGE_OUT;
} else if (dir == "inbound") {
opts.direction = TRI_EDGE_IN;
} else if (dir == "any") {
opts.direction = TRI_EDGE_ANY;
} else {
TRI_V8_THROW_TYPE_ERROR("expecting direction to be 'outbound', 'inbound' or 'any'");
}
}
// Parse use distinct
v8::Local<v8::String> keyDistinct= TRI_V8_ASCII_STRING("distinct");
if (options->Has(keyDistinct) ) {
opts.distinct = TRI_ObjectToBoolean(options->Get(keyDistinct));
}
// Parse includeData
v8::Local<v8::String> keyIncludeData = TRI_V8_ASCII_STRING("includeData");
if (options->Has(keyIncludeData)) {
includeData = TRI_ObjectToBoolean(options->Get(keyIncludeData));
}
}
vector<TRI_voc_cid_t> readCollections;
vector<TRI_voc_cid_t> writeCollections;
V8ResolverGuard resolverGuard(vocbase);
CollectionNameResolver const* resolver = resolverGuard.getResolver();
readCollections.push_back(resolver->getCollectionId(vertexCollectionName));
readCollections.push_back(resolver->getCollectionId(edgeCollectionName));
ExplicitTransaction* trx = nullptr;
int res = 0;
CollectionNameResolver const* resolver = resolverGuard.getResolver();
for (auto it : edgeCollectionNames) {
readCollections.push_back(resolver->getCollectionId(it));
}
for (auto it : vertexCollectionNames) {
readCollections.push_back(resolver->getCollectionId(it));
}
unordered_map<TRI_voc_cid_t, CollectionBarrierInfo> barriers;
// Start the transaction
@ -2204,21 +2198,43 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
trx = beginTransaction(vocbase, readCollections, writeCollections,
resolver, barriers);
} catch (int e) {
// Nothing to clean up. Throw the error to V8
TRI_V8_THROW_EXCEPTION(e);
}
TRI_voc_cid_t edgeCid = resolver->getCollectionId(edgeCollectionName);
TRI_ASSERT(barriers.find(edgeCid) != barriers.end());
vector<EdgeCollectionInfo*> edgeCollectionInfos;
for(auto it : edgeCollectionNames) {
auto cid = resolver->getCollectionId(it);
auto colObj = barriers.find(cid)->second.col->_collection->_collection;
edgeCollectionInfos.push_back(new EdgeCollectionInfo(
cid,
colObj,
HopWeightCalculator()
));
}
vector<VertexCollectionInfo*> vertexCollectionInfos;
for(auto it : vertexCollectionNames) {
auto cid = resolver->getCollectionId(it);
auto colObj = barriers.find(cid)->second.col;
vertexCollectionInfos.push_back(new VertexCollectionInfo(
cid,
colObj
));
}
try {
opts.start = idStringToVertexId(resolver, startVertex);
} catch (int e) {
// Id string might have illegal collection name
trx->finish(e);
delete trx;
TRI_V8_THROW_EXCEPTION(e);
}
vector<VertexId> neighbors;
try {
neighbors = TRI_RunNeighborsSearch(
isolate,
vocbase,
vertexCollectionName,
edgeCollectionName,
startVertex,
resolver,
barriers.find(edgeCid)->second.col->_collection->_collection,
edgeCollectionInfos,
opts
);
} catch (int e) {
@ -2227,7 +2243,7 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
TRI_V8_THROW_EXCEPTION(e);
}
auto result = vertexIdsToV8(isolate, trx, resolver, neighbors, barriers, true);
auto result = vertexIdsToV8(isolate, trx, resolver, neighbors, barriers, includeData);
trx->finish(res);
delete trx;

View File

@ -6490,15 +6490,17 @@ function AQL_NEIGHBORS (vertexCollection,
edgeCollection,
vertex,
direction,
examples) {
examples,
options) {
'use strict';
vertex = TO_ID(vertex, vertexCollection);
/*
options = options || {};
options.direction = direction;
options.examples = examples;
if (examples === undefined) {
return [CPP_NEIGHBORS(vertexCollection, edgeCollection, vertex, {direction: direction})];
return CPP_NEIGHBORS([vertexCollection], [edgeCollection], vertex, options);
}
*/
var edges = AQL_EDGES(edgeCollection, vertex, direction);
return FILTERED_EDGES(edges, vertex, direction, examples);

View File

@ -150,26 +150,38 @@ function ahuacatlQueryEdgesTestSuite () {
testNeighborsAny : function () {
var actual;
var v1 = "UnitTestsAhuacatlVertex/v1";
var v2 = "UnitTestsAhuacatlVertex/v2";
var v3 = "UnitTestsAhuacatlVertex/v3";
var v4 = "UnitTestsAhuacatlVertex/v4";
var v5 = "UnitTestsAhuacatlVertex/v5";
var v6 = "UnitTestsAhuacatlVertex/v6";
var v7 = "UnitTestsAhuacatlVertex/v7";
var v8 = "UnitTestsAhuacatlVertex/v8";
var theFox = "UnitTestsAhuacatlVertex/thefox";
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
var queryEnd = "', 'any') SORT n RETURN n";
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'any') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v2", "v1->v2" ], [ "v3", "v1->v3" ] ]);
actual = getQueryResults(queryStart + v1 + queryEnd);
assertEqual(actual, [ v2, v3 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'any') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v1", "v1->v2" ], [ "v3", "v2->v3" ], [ "v4", "v4->v2" ] ]);
actual = getQueryResults(queryStart + v2 + queryEnd);
assertEqual(actual, [ v1, v3, v4 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'any') SORT n.vertex._key, n.edge.what RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v1", "v1->v3"], [ "v2", "v2->v3" ], [ "v4", "v3->v4" ], [ "v6", "v3->v6" ], [ "v6", "v6->v3"], [ "v7", "v3->v7" ], [ "v7", "v7->v3" ] ]);
// v6 and v7 are neighbors twice
actual = getQueryResults(queryStart + v3 + queryEnd);
assertEqual(actual, [ v1, v2, v4, v6, v7 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'any') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v8 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'any') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v5 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'any') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + theFox + queryEnd);
assertEqual(actual, [ ]);
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'any') SORT n.vertex._key RETURN n.vertex._key");
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
},
////////////////////////////////////////////////////////////////////////////////
@ -178,26 +190,37 @@ function ahuacatlQueryEdgesTestSuite () {
testNeighborsIn : function () {
var actual;
var v1 = "UnitTestsAhuacatlVertex/v1";
var v2 = "UnitTestsAhuacatlVertex/v2";
var v3 = "UnitTestsAhuacatlVertex/v3";
var v4 = "UnitTestsAhuacatlVertex/v4";
var v5 = "UnitTestsAhuacatlVertex/v5";
var v6 = "UnitTestsAhuacatlVertex/v6";
var v7 = "UnitTestsAhuacatlVertex/v7";
var v8 = "UnitTestsAhuacatlVertex/v8";
var theFox = "UnitTestsAhuacatlVertex/thefox";
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
var queryEnd = "', 'inbound') SORT n RETURN n";
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
actual = getQueryResults(queryStart + v1 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v1", "v1->v2" ], [ "v4", "v4->v2" ] ]);
actual = getQueryResults(queryStart + v2 + queryEnd);
assertEqual(actual, [v1, v4]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'inbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v1", "v1->v3"], [ "v2", "v2->v3" ], [ "v6", "v6->v3"], [ "v7", "v7->v3" ] ]);
actual = getQueryResults(queryStart + v3 + queryEnd);
assertEqual(actual, [v1, v2, v6, v7]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v8 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v5 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + theFox + queryEnd);
assertEqual(actual, [ ]);
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'inbound') SORT n.vertex._key RETURN n.vertex._key");
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
},
////////////////////////////////////////////////////////////////////////////////
@ -234,26 +257,37 @@ function ahuacatlQueryEdgesTestSuite () {
testNeighborsOut : function () {
var actual;
var v1 = "UnitTestsAhuacatlVertex/v1";
var v2 = "UnitTestsAhuacatlVertex/v2";
var v3 = "UnitTestsAhuacatlVertex/v3";
var v4 = "UnitTestsAhuacatlVertex/v4";
var v5 = "UnitTestsAhuacatlVertex/v5";
var v6 = "UnitTestsAhuacatlVertex/v6";
var v7 = "UnitTestsAhuacatlVertex/v7";
var v8 = "UnitTestsAhuacatlVertex/v8";
var theFox = "UnitTestsAhuacatlVertex/thefox";
var queryStart = "FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, '";
var queryEnd = "', 'outbound') SORT n RETURN n";
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v1', 'outbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v2", "v1->v2" ], [ "v3", "v1->v3" ] ]);
actual = getQueryResults(queryStart + v1 + queryEnd);
assertEqual(actual, [ v2, v3 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v2', 'outbound') SORT n.vertex._key RETURN [ n.vertex._key, n.edge.what ]");
assertEqual(actual, [ [ "v3", "v2->v3" ] ]);
actual = getQueryResults(queryStart + v2 + queryEnd);
assertEqual(actual, [ v3 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v3', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
assertEqual(actual, [ "v4", "v6", "v7" ]);
actual = getQueryResults(queryStart + v3 + queryEnd);
assertEqual(actual, [ v4, v6, v7 ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v8', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v8 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/v5', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + v5 + queryEnd);
assertEqual(actual, [ ]);
actual = getQueryResults("FOR n IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'UnitTestsAhuacatlVertex/thefox', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
actual = getQueryResults(queryStart + theFox + queryEnd);
assertEqual(actual, [ ]);
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, "FOR e IN NEIGHBORS(UnitTestsAhuacatlVertex, UnitTestsAhuacatlEdge, 'thefox/thefox', 'outbound') SORT n.vertex._key RETURN n.vertex._key");
assertQueryError(errors.ERROR_ARANGO_COLLECTION_NOT_FOUND.code, queryStart + "thefox/thefox" + queryEnd);
}
};