1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel

This commit is contained in:
scottashton 2014-06-16 16:33:46 +02:00
commit 9917d68129
11 changed files with 3171 additions and 341 deletions

View File

@ -38,11 +38,87 @@ To add further edge definitions to the array one must call:
!SUBSUBSECTION Undirected Relation
<!-- @startDocuBlock JSF_general_graph_undirectedRelationDefinition -->
<br />
`general-graph._undirectedRelationDefinition(relationName, vertexCollections)`
*Define an undirected relation.*
<br />
Defines an undirected relation with the name *relationName* using the
list of *vertexCollections*. This relation allows the user to store
edges in any direction between any pair of vertices within the
*vertexCollections*.
<br />
@EXAMPLES
<br />
To define simple relation with only one vertex collection:
<br />
```
arangosh> var graph = require("org/arangodb/general-graph");
arangosh> graph._undirectedRelationDefinition("friend", "user");
{
"collection" : "friend",
"from" : [
"user"
],
"to" : [
"user"
]
}
```
<br />
To define a relation between several vertex collections:
<br />
```
arangosh> var graph = require("org/arangodb/general-graph");
arangosh> graph._undirectedRelationDefinition("marriage", ["female", "male"]);
{
"collection" : "marriage",
"from" : [
"female",
"male"
],
"to" : [
"female",
"male"
]
}
```
!SUBSUBSECTION Directed Relation
<!-- @startDocuBlock JSF_general_graph_undirectedRelationDefinition -->
<br />
`general-graph._directedRelationDefinition(relationName, fromVertexCollections, toVertexCollections)`
*Define a directed relation.*
<br />
The *relationName* defines the name of this relation and references to the underlying edge collection.
The *fromVertexCollections* is an Array of document collections holding the start vertices.
The *toVertexCollections* is an Array of document collections holding the target vertices.
Relations are only allowed in the direction from any collection in *fromVertexCollections*
to any collection in *toVertexCollections*.
<br />
@EXAMPLES
<br />
```
arangosh> var graph = require("org/arangodb/general-graph");
arangosh> graph._directedRelationDefinition("has_bought", ["Customer", "Company"], ["Groceries", "Electronics"]);
{
"collection" : "has_bought",
"from" : [
"Customer",
"Company"
],
"to" : [
"Groceries",
"Electronics"
]
}
```
!SUBSUBSECTION Complete Example to create a graph
@ -77,20 +153,74 @@ alternative call:
!SUBSECTION Orphan Collections
Each graph has an orphan collection. It consists of arbitrary many vertex collection (type *document*), that are not
used in an edge definition of the graph. If the graph is extended with an edge definition, which is part of the orphan
collection, it will be removed from the orphan collection automatically.
used in an edge definition of the graph. If the graph is extended with an edge definition using one of the orphans,
it will be removed from the orphan collection automatically.
!SUBSUBSECTION Add
<!-- @startDocuBlock JSF_general_graph__addOrphanCollection -->
Adds a vertex collection to the set of orphan collections of the graph. If the
collection does not exist, it will be created.
<br />
`general-graph._addOrphanCollection(orphanCollectionName, createCollection)`
<br />
*orphanCollectionName* - string : name of vertex collection.
*createCollection* - bool : if true the collection will be created if it does not exist. Default: true.
<br />
@EXAMPLES
<br />
```
arangosh> var graph = require("org/arangodb/general-graph")
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
arangosh> var g = graph._create("myGraph", [ed1, ed2]);
ReferenceError: ed2 is not defined
```
<br />
!SUBSUBSECTION Read
<!-- @startDocuBlock JSF_general_graph__getOrphanCollections -->
Returns all vertex collections of the graph, that are not used in an edge definition.
<br />
`general-graph._getOrphanCollections()`
<br />
@EXAMPLES
<br />
```
arangosh> var graph = require("org/arangodb/general-graph")
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
arangosh> var g = graph._create("myGraph", [ed1]);
[ArangoError 1925: graph already exists]
```
<br />
!SUBSUBSECTION Remove
<!-- @startDocuBlock JSF_general_graph__removeOrphanCollection -->
Removes an orphan collection from the graph and deletes the collection, if it is not
used in any graph.
<br />
`general-graph._removeOrphanCollection()`
<br />
*orphanCollectionName* - string : name of vertex collection.
*dropCollection* - bool : if true the collection will be dropped if it is not used in any graph.
Default: true.
<br />
@EXAMPLES
<br />
```
arangosh> var graph = require("org/arangodb/general-graph")
arangosh> var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
arangosh> var g = graph._create("myGraph", [ed1]);
[ArangoError 1925: graph already exists]
```
<br />
!SUBSECTION Read a graph
@ -122,47 +252,324 @@ dropCollections: bool - optional. *true* all collections of the graph will be de
!SUBSECTION Save
<!-- @startDocuBlock JSF_general_graph_vertex_collection_save -->
Creates and saves a new vertex in collection *vertexCollectionName*
<br />
`general-graph.vertexCollectionName.save(data)`
<br />
*data*: json - data of vertex
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.male.save({name: "Floyd", _key: "floyd"});
{
"error" : false,
"_id" : "male/floyd",
"_rev" : "91260521",
"_key" : "floyd"
}
```
<br />
!SUBSECTION Replace
<!-- @startDocuBlock JSF_general_graph_vertex_collection_replace -->
Replaces the data of a vertex in collection *vertexCollectionName*
<br />
`general-graph.vertexCollectionName.replace(vertexId, data, options)`
<br />
*vertexId*: string - id of the vertex
*data*: json - data of vertex
*options*: json - (optional) - see collection documentation
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.male.save({neym: "Jon", _key: "john"});
{
"error" : false,
"_id" : "male/john",
"_rev" : "31360617",
"_key" : "john"
}
arangosh> g.male.replace("male/john", {name: "John"});
{
"error" : false,
"_id" : "male/john",
"_rev" : "31557225",
"_key" : "john"
}
```
<br />
!SUBSECTION Update
<!-- @startDocuBlock JSF_general_graph_vertex_collection_update -->
Updates the data of a vertex in collection *vertexCollectionName*
<br />
`general-graph.vertexCollectionName.update(vertexId, data, options)`
<br />
*vertexId*: string - id of the vertex
*data*: json - data of vertex
*options*: json - (optional) - see collection documentation
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.female.save({name: "Lynda", _key: "linda"});
{
"error" : false,
"_id" : "female/linda",
"_rev" : "79201897",
"_key" : "linda"
}
arangosh> g.female.update({name: "Linda", _key: "linda"});
TypeError: Object #<Object> has no method 'split'
```
<br />
!SUBSECTION Remove
<!-- @startDocuBlock JSF_general_graph_vertex_collection_remove -->
Removes a vertex in collection *vertexCollectionName*
<br />
`general-graph.vertexCollectionName.remove(vertexId, options)`
<br />
Additionally removes all ingoing and outgoing edges of the vertex recursively
(see [edge remove](#edge.remove)).
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.male.save({name: "Kermit", _key: "kermit"});
{
"error" : false,
"_id" : "male/kermit",
"_rev" : "83068521",
"_key" : "kermit"
}
arangosh> db._exists("male/kermit")
true
arangosh> g.male.remove("male/kermit")
true
arangosh> db._exists("male/kermit")
false
```
<br />
!SECTION Edge
!SUBSECTION Save
<!-- @startDocuBlock JSF_general_graph_edge_collection_save -->
Creates and saves a new edge from vertex *from* to vertex *to* in
collection *edgeCollectionName*
<br />
`general-graph.edgeCollectionName.save(from, to, data)`
<br />
*from*: string - id of outgoing vertex
*to*: string - of ingoing vertex
*data*: json - data of edge
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.relation.save("male/bob", "female/alice", {type: "married", _key: "bobAndAlice"});
{
"error" : false,
"_id" : "relation/bobAndAlice",
"_rev" : "45909609",
"_key" : "bobAndAlice"
}
```
<br />
If the collections of *from* and *to* are not defined in an edgeDefinition of the graph,
the edge will not be stored.
<br />
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.relation.save("relation/aliceAndBob", "female/alice", {type: "married", _key: "bobAndAlice"});
Edge is not allowed between relation/aliceAndBob and female/alice.
```
!SUBSECTION Replace
<!-- @startDocuBlock JSF_general_graph_edge_collection_replace -->
Replaces the data of an edge in collection *edgeCollectionName*
<br />
`general-graph.edgeCollectionName.replace(edgeId, data, options)`
<br />
*edgeId*: string - id of the edge
*data*: json - data of edge
*options*: json - (optional) - see collection documentation
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.relation.save("female/alice", "female/diana", {typo: "nose", _key: "aliceAndDiana"});
{
"error" : false,
"_id" : "relation/aliceAndDiana",
"_rev" : "27362921",
"_key" : "aliceAndDiana"
}
arangosh> g.relation.replace("relation/aliceAndDiana", {type: "knows"});
{
"error" : false,
"_id" : "relation/aliceAndDiana",
"_rev" : "27559529",
"_key" : "aliceAndDiana"
}
```
<br />
!SUBSECTION Update
<!-- @startDocuBlock JSF_general_graph_edge_collection_update -->
Updates the data of an edge in collection *edgeCollectionName*
<br />
`general-graph.edgeCollectionName.update(edgeId, data, options)`
<br />
*edgeId*: string - id of the edge
*data*: json - data of edge
*options*: json - (optional) - see collection documentation
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.relation.save("female/alice", "female/diana", {type: "knows", _key: "aliceAndDiana"});
{
"error" : false,
"_id" : "relation/aliceAndDiana",
"_rev" : "127108713",
"_key" : "aliceAndDiana"
}
arangosh> g.relation.update("relation/aliceAndDiana", {type: "quarrelled", _key: "aliceAndDiana"});
{
"error" : false,
"_id" : "relation/aliceAndDiana",
"_rev" : "127305321",
"_key" : "aliceAndDiana"
}
```
<br />
!SUBSECTION Remove
<!-- @startDocuBlock JSF_general_graph_edge_collection_remove -->
Removes an edge in collection *edgeCollectionName*
<br />
`general-graph.edgeCollectionName.remove(edgeId, options)`
<br />
If this edge is used as a vertex by another edge, the other edge will be removed (recursively).
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g.relation.save("female/alice", "female/diana", {_key: "aliceAndDiana"});
{
"error" : false,
"_id" : "relation/aliceAndDiana",
"_rev" : "141657705",
"_key" : "aliceAndDiana"
}
arangosh> db._exists("relation/aliceAndDiana")
true
arangosh> g.relation.remove("relation/aliceAndDiana")
true
arangosh> db._exists("relation/aliceAndDiana")
false
```
<br />
!SECTION Vertices
!SUBSECTION Get vertex *from* of an edge
<!-- @startDocuBlock JSF_general_graph_getFromVertex -->
Get the vertex of an edge defined as *_from*
<br />
`general-graph._getFromVertex(edgeId)`
<br />
Returns the vertex defined with the attribute *_from* of the edge with *edgeId* as its *_id*.
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g._getFromVertex("relation/aliceAndBob")
{
"name" : "Alice",
"_id" : "female/alice",
"_rev" : "175670889",
"_key" : "alice"
}
```
<br />
!SUBSECTION Get vertex *to* of an edge
<!-- @startDocuBlock JSF_general_graph_getToVertex -->
Get the vertex of an edge defined as *_to*
<br />
`general-graph._getToVertex(edgeId)`
<br />
Returns the vertex defined with the attribute *_to* of the edge with *edgeId* as its *_id*.
<br />
@EXAMPLES
<br />
```
arangosh> var examples = require("org/arangodb/graph-examples/example-graph.js");
arangosh> var g = examples.loadGraph("social");
arangosh> g._getToVertex("relation/aliceAndBob")
{
"name" : "Bob",
"_id" : "male/bob",
"_rev" : "40666729",
"_key" : "bob"
}
```
<br />

View File

@ -30,17 +30,3 @@ Then you can run the test suite using *jsunity.runTest*
2012-01-28T19:10:23Z [10671] INFO 1 test passed
2012-01-28T19:10:23Z [10671] INFO 0 tests failed
2012-01-28T19:10:23Z [10671] INFO 1 millisecond elapsed
!SUBSECTION Running jsUnity Tests with Coverage
You can use the coverage tool
[node-jscoverage](https://github.com/visionmedia/node-jscoverage)
Assume that your file live in a directory called `lib`. Use
node-jscoverage lib lib-cov
to create a copy of the JavaScript files with coverage information. Start the
ArangoDB with these files and use *jsunity.runCoverage* instead of
*jsunity.runTest*.

View File

@ -36,18 +36,4 @@ Then you can run the test suite using @FN{jsunity.runTest}
2012-01-28T19:10:23Z [10671] INFO 0 tests failed
2012-01-28T19:10:23Z [10671] INFO 1 millisecond elapsed
Running jsUnity Tests with Coverage{#jsUnityRunningCoverage}
============================================================
You can use the coverage tool <a
href="https://github.com/visionmedia/node-jscoverage">@LIT{node-jscoverage}</a>.
Assume that your file live in a directory called `lib`. Use
node-jscoverage lib lib-cov
to create a copy of the JavaScript files with coverage information. Start the
ArangoDB with these files and use @FN{jsunity.runCoverage} instead of
@FN{jsunity.runTest}.
@BNAVIGATE_jsUnity

View File

@ -1017,7 +1017,7 @@ int ArangoServer::runUnitTests (TRI_vocbase_t* vocbase) {
context->_context->Global()->Set(v8::String::New("SYS_UNIT_TESTS_RESULT"), v8::True());
// run tests
char const* input = "require(\"jsunity\").runCommandLineTests();";
char const* input = "require(\"test_runner\").runCommandLineTests();";
TRI_ExecuteJavaScriptString(context->_context, v8::String::New(input), name, true);
if (tryCatch.HasCaught()) {

View File

@ -1555,7 +1555,7 @@ static bool RunUnitTests (v8::Handle<v8::Context> context) {
context->Global()->Set(v8::String::New("SYS_UNIT_TESTS_RESULT"), v8::True());
// run tests
char const* input = "require(\"jsunity\").runCommandLineTests();";
char const* input = "require(\"test_runner\").runCommandLineTests();";
v8::Local<v8::String> name(v8::String::New("(arangosh)"));
TRI_ExecuteJavaScriptString(context, v8::String::New(input), name, true);

54
js/common/modules/jasmine.js Executable file
View File

@ -0,0 +1,54 @@
/*jslint indent: 2, nomen: true, maxlen: 120, regexp: true, todo: true */
/*global module, require, exports, print */
/** Jasmine Wrapper
*
* This file is based upon Jasmine's boot.js,
* but adjusted to work with ArangoDB
*
* jasmine/core: This is an unmodified copy of Jasmine's Standalone Version
* jasmine/reporter: A reporter written for ArangoDB
*/
var jasmine = require('jasmine/core'),
_ = require('underscore'),
fs = require('fs'),
Reporter = require('jasmine/reporter').Reporter;
jasmine = jasmine.core(jasmine);
exports.executeTestSuite = function (specFileNames, options) {
'use strict';
var sandbox = jasmine.getEnv(),
format = options.format || 'progress';
// Explicitly add require
sandbox.require = require;
/**
* The `jsApiReporter` also receives spec results, and is used by any environment
* that needs to extract the results from JavaScript.
*/
var jsApiReporter = new jasmine.JsApiReporter({
timer: new jasmine.Timer()
});
sandbox.addReporter(jsApiReporter);
/**
* The `arangoReporter` does the reporting to the console
*/
var arangoReporter = new Reporter({ format: format });
sandbox.addReporter(arangoReporter);
var _ = require('underscore'),
internal = require('internal');
_.each(specFileNames, function (specFileName) {
var spec = fs.read(specFileName);
internal.executeScript(spec, sandbox, specFileName);
});
sandbox.execute();
return !arangoReporter.hasErrors();
};

2402
js/common/modules/jasmine/core.js Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
/*jslint indent: 2, nomen: true, maxlen: 120, regexp: true, todo: true */
/*global module, require, exports, print */
// Reporter
// progress [default]: Dots
// documentation: Group and example names
var Reporter,
_ = require('underscore'),
internal = require('internal'),
inspect = internal.inspect,
failureColor = internal.COLORS.COLOR_RED,
successColor = internal.COLORS.COLOR_GREEN,
commentColor = internal.COLORS.COLOR_BLUE,
resetColor = internal.COLORS.COLOR_RESET,
pendingColor = internal.COLORS.COLOR_YELLOW
p = function (x) { print(inspect(x)); };
var repeatString = function(str, num) {
return new Array(num + 1).join(str);
};
var indenter = function(indentation) {
return function (str) {
return repeatString(" ", indentation) + str;
};
};
var indent = function(message, indentation) {
var lines = message.split("\n");
return _.map(lines, indenter(indentation)).join("\n");
};
// "at Function.main (test.js:19:11)"
var fileInfoPattern = /\(([^:]+):[^)]+\)/;
var parseFileName = function(stack) {
var parsedStack = _.last(_.filter(stack.split("\n"), function(line) {
return fileInfoPattern.test(line);
}));
return fileInfoPattern.exec(parsedStack)[1];
};
Reporter = function (options) {
options = options || {};
this.format = options.format || 'progress';
this.failures = [];
};
_.extend(Reporter.prototype, {
jasmineStarted: function(options) {
this.totalSpecs = options.totalSpecsDefined || 0;
this.failedSpecs = [];
this.pendingSpecs = [];
this.start = new Date();
print();
},
hasErrors: function() {
return this.failedSpecs.length > 0;
},
jasmineDone: function() {
if (this.format === 'progress') {
print('\n');
}
if (this.failures.length > 0) {
this.printFailureInfo();
}
if (this.pendingSpecs.length > 0) {
this.printPendingInfo();
}
this.printFooter();
if (this.failures.length > 0) {
this.printFailedExamples();
}
print();
},
suiteStarted: function(result) {
if (this.format === 'documentation') {
print(result.description);
}
},
suiteDone: function() {
if (this.format === 'documentation') {
print();
}
},
specStarted: function(result) {
if (!_.isUndefined(this.currentSpec)) {
this.pending(this.currentSpec.description, this.currentSpec);
}
this.currentSpec = result;
},
specDone: function(result) {
this.currentSpec = undefined;
if (_.isEqual(result.status, 'passed')) {
this.pass(result.description);
} else {
this.fail(result.description, result);
}
},
pending: function (testName, result) {
this.pendingSpecs.push(result);
if (this.format === 'progress') {
printf("%s", pendingColor + "*" + resetColor);
} else if (this.format === 'documentation') {
print(pendingColor + " " + testName + " [PENDING]" + resetColor);
}
},
pass: function (testName) {
if (this.format === 'progress') {
printf("%s", successColor + "." + resetColor);
} else if (this.format === 'documentation') {
print(successColor + " " + testName + resetColor);
}
},
printFailureMessage: function(testName) {
if (this.format === 'progress') {
printf("%s", failureColor + "F" + resetColor);
} else if (this.format === 'documentation') {
print(failureColor + " " + testName + " [FAILED]" + resetColor);
}
},
fail: function (testName, result) {
var failedExpectations = result.failedExpectations;
this.failedSpecs.push(result.fullName);
this.printFailureMessage(testName);
_.each(failedExpectations, function(failedExpectation) {
this.failures.push({
fullName: result.fullName,
failedExpectation: failedExpectation,
fileName: parseFileName(failedExpectation.stack)
});
}, this);
},
printFailureInfo: function () {
print("Failures:\n");
_.each(this.failures, function(failure, index) {
var failedExpectation = failure.failedExpectation;
print(" " + index + ") " + failure.fullName);
print(failureColor + indent(failedExpectation.stack, 6) + resetColor);
});
},
printPendingInfo: function () {
print("Pending:\n");
_.each(this.pendingSpecs, function(pending) {
print(pendingColor + " " + pending.fullName + resetColor);
});
},
printFooter: function () {
var end = new Date(),
timeInMilliseconds = end - this.start,
color,
message = this.totalSpecs + ' example, ' + this.failedSpecs.length + ' failures';
if (this.failedSpecs.length > 0) {
color = failureColor;
} else if (this.pendingSpecs.length > 0) {
color = pendingColor;
message += ', ' + this.pendingSpecs.length + ' pending';
} else {
color = successColor;
}
print();
print('Finished in ' + (timeInMilliseconds / 1000) + ' seconds');
print(color + message + resetColor);
},
printFailedExamples: function () {
print("\nFailed examples:\n");
_.each(this.failures, function(failure) {
var repeatAction = "arangod --javascript.unit-tests " + failure.fileName + " /tmp/arangodb_test";
print(failureColor + repeatAction + commentColor + " # " + failure.fullName + resetColor);
});
}
});
exports.Reporter = Reporter;

View File

@ -57,235 +57,6 @@ jsUnity.results.end = function (passed, failed, duration) {
print();
};
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief pad the given string to the maximum width provided
///
/// From: http://www.bennadel.com/blog/1927-Faking-Context-In-Javascript-s-Function-Constructor.htm
////////////////////////////////////////////////////////////////////////////////
function FunctionContext (func) {
var body = " for (var __i in context) {"
+ " eval('var ' + __i + ' = context[__i];');"
+ " }"
+ " return " + func + ";";
return new Function("context", body);
}
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Expresso
/// @{
///
/// based on:
///
/// Expresso
/// Copyright(c) TJ Holowaychuk <tj@vision-media.ca>
/// (MIT Licensed)
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief pad the given string to the maximum width provided
////////////////////////////////////////////////////////////////////////////////
function lpad (str, width) {
str = String(str);
var n = width - str.length;
if (n < 1) {
return str;
}
while (n--) {
str = ' ' + str;
}
return str;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief pad the given string to the maximum width provided
////////////////////////////////////////////////////////////////////////////////
function rpad (str, width) {
str = String(str);
var n = width - str.length;
if (n < 1) {
return str;
}
while (n--) {
str = str + ' ';
}
return str;
}
////////////////////////////////////////////////////////////////////////////////
/// Total coverage for the given file data.
////////////////////////////////////////////////////////////////////////////////
function coverage (data, val) {
var n = 0;
for (var i = 0, len = data.length; i < len; ++i) {
if (data[i] !== undefined && data[i] == val) {
++n;
}
}
return n;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief populate code coverage data
////////////////////////////////////////////////////////////////////////////////
function populateCoverage (cov) {
var boring = false;
cov.LOC = 0;
cov.SLOC = 0;
cov.totalFiles = 0;
cov.totalHits = 0;
cov.totalMisses = 0;
cov.coverage = 0;
for (var name in cov) {
var file = cov[name];
if (Array.isArray(file)) {
++cov.totalFiles;
if (! file.source) {
file.source = [];
}
cov.totalHits += file.totalHits = coverage(file, true);
cov.totalMisses += file.totalMisses = coverage(file, false);
file.totalLines = file.totalHits + file.totalMisses;
cov.SLOC += file.SLOC = file.totalLines;
cov.LOC += file.LOC = file.source.length;
file.coverage = (file.totalHits / file.totalLines) * 100;
var width = file.source.length.toString().length;
file.sourceLines = file.source.map(function(line, i) {
++i;
var hits = lpad(file[i] === 0 ? 0 : (file[i] || ' '), 3);
if (! boring) {
if (file[i] === 0) {
hits = '\x1b[31m' + hits + '\x1b[0m';
line = '\x1b[41m' + line + '\x1b[0m';
}
else {
hits = '\x1b[32m' + hits + '\x1b[0m';
}
}
return '\n ' + lpad(i, width) + ' | ' + hits + ' | ' + line;
}).join('');
}
}
cov.coverage = (cov.totalHits / cov.SLOC) * 100;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief report test coverage in tabular format
////////////////////////////////////////////////////////////////////////////////
function reportCoverage (cov, files) {
print('\n Test Coverage\n');
var sep = ' +------------------------------------------+----------+------+------+--------+';
var lastSep = ' +----------+------+------+--------+';
var line;
print(sep);
print(' | filename | coverage | LOC | SLOC | missed |');
print(sep);
for (var name in cov) {
var file = cov[name];
if (Array.isArray(file)) {
line = '';
line += ' | ' + rpad(name, 40);
line += ' | ' + lpad(file.coverage.toFixed(2), 8);
line += ' | ' + lpad(file.LOC, 4);
line += ' | ' + lpad(file.SLOC, 4);
line += ' | ' + lpad(file.totalMisses, 6);
line += ' |';
print(line);
}
}
print(sep);
line = '';
line += ' ' + rpad('', 40);
line += ' | ' + lpad(cov.coverage.toFixed(2), 8);
line += ' | ' + lpad(cov.LOC, 4);
line += ' | ' + lpad(cov.SLOC, 4);
line += ' | ' + lpad(cov.totalMisses, 6);
line += ' |';
print(line);
print(lastSep);
var match = null;
if (files == true) {
match = function(name) {
return name.match(/\.js$/);
}
}
else if (files != null) {
var fl = {};
if (typeof files == "string") {
fl[files] = true;
}
else {
for (var i = 0; i < files.length; ++i) {
fl[files[i]] = true;
}
}
match = function(name) {
return name in fl;
}
}
if (match != null) {
for (var name in cov) {
if (match(name)) {
var file = cov[name];
if (file.coverage < 100) {
print('\n ' + name + ':');
print(file.sourceLines);
print('\n');
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
@ -383,47 +154,6 @@ function RunTest (path) {
return f();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief runs a JSUnity test file with coverage
////////////////////////////////////////////////////////////////////////////////
function RunCoverage (path, files) {
RunTest(path);
populateCoverage(_$jscoverage);
reportCoverage(_$jscoverage, files);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief runs tests from command-line
////////////////////////////////////////////////////////////////////////////////
function RunCommandLineTests () {
var result = true;
var unitTests = internal.unitTests();
for (var i = 0; i < unitTests.length; ++i) {
var file = unitTests[i];
print();
print("running tests from file '" + file + "'");
try {
var ok = RunTest(file);
result = result && ok;
}
catch (err) {
print("cannot run test file '" + file + "': " + err);
print(err.stack);
result = false;
}
internal.wait(0); // force GC
}
internal.setUnitTestsResult(result);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -441,8 +171,6 @@ exports.jsUnity = jsUnity;
exports.run = Run;
exports.done = Done;
exports.runTest = RunTest;
exports.runCoverage = RunCoverage;
exports.runCommandLineTests = RunCommandLineTests;
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -2508,10 +2508,10 @@ Graph.prototype._amountCommonProperties = function(vertex1Example, vertex2Exampl
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__extendEdgeDefinitions}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = examples._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
/// var g = examples._create("myGraph", [ed1]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = graph._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
/// var g = graph._create("myGraph", [ed1]);
/// g._extendEdgeDefinitions(ed2);
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2661,10 +2661,10 @@ var changeEdgeDefinitionsForGraph = function(graph, edgeDefinition, newCollectio
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__editEdgeDefinition}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = examples._directedRelationDefinition("myEC1", ["myVC2"], ["myVC3"]);
/// var g = examples._create("myGraph", [ed1, ed2]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = graph._directedRelationDefinition("myEC1", ["myVC2"], ["myVC3"]);
/// var g = graph._create("myGraph", [ed1, ed2]);
/// g._editEdgeDefinition(ed2, true);
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2730,10 +2730,10 @@ Graph.prototype._editEdgeDefinitions = function(edgeDefinition) {
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__deleteEdgeDefinition}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = examples._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
/// var g = examples._create("myGraph", [ed1, ed2]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var ed2 = graph._directedRelationDefinition("myEC2", ["myVC1"], ["myVC3"]);
/// var g = graph._create("myGraph", [ed1, ed2]);
/// g._deleteEdgeDefinition("myEC1");
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2792,9 +2792,9 @@ Graph.prototype._deleteEdgeDefinition = function(edgeCollection) {
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__addOrphanCollection}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1, ed2]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = graph._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3", true);
/// @END_EXAMPLE_ARANGOSH_OUTPUT
///
@ -2842,9 +2842,9 @@ Graph.prototype._addOrphanCollection = function(orphanCollectionName, createColl
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__getOrphanCollections}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = graph._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3", true);
/// g._getOrphanCollections();
/// @END_EXAMPLE_ARANGOSH_OUTPUT
@ -2871,9 +2871,9 @@ Graph.prototype._getOrphanCollections = function() {
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_OUTPUT{general_graph__removeOrphanCollections}
/// var examples = require("org/arangodb/graph-examples/example-graph.js");
/// var ed1 = examples._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = examples._create("myGraph", [ed1]);
/// var graph = require("org/arangodb/general-graph")
/// var ed1 = graph._directedRelationDefinition("myEC1", ["myVC1"], ["myVC2"]);
/// var g = graph._create("myGraph", [ed1]);
/// g._addOrphanCollection("myVC3", true);
/// g._addOrphanCollection("myVC4", true);
/// g._getOrphanCollections();

View File

@ -0,0 +1,74 @@
/*jslint indent: 2, nomen: true, maxlen: 120, regexp: true, todo: true */
/*global module, require, exports, print */
var runTest = require('jsunity').runTest,
_ = require('underscore'),
internal = require('internal'),
runJSUnityTests,
runJasmineTests,
runCommandLineTests;
////////////////////////////////////////////////////////////////////////////////
/// @brief runs all jsunity tests
////////////////////////////////////////////////////////////////////////////////
runJSUnityTests = function (tests) {
'use strict';
var result = true;
_.each(tests, function (file) {
print("\nRunning JSUnity test from file '" + file + "'");
try {
result = result && runTest(file);
} catch (err) {
print("cannot run test file '" + file + "': " + err);
print(err.stack);
result = false;
}
internal.wait(0); // force GC
});
return result;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief runs all jsunity tests
////////////////////////////////////////////////////////////////////////////////
runJasmineTests = function (testFiles, options) {
'use strict';
var result = true;
if (testFiles.length > 0) {
print('\nRunning Jasmine Tests: ' + testFiles.join(', '));
result = require('jasmine').executeTestSuite(testFiles, options);
}
return result;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief runs tests from command-line
////////////////////////////////////////////////////////////////////////////////
runCommandLineTests = function (opts) {
'use strict';
var result = true,
options = opts || {},
jasmineReportFormat = options.jasmineReportFormat || 'progress',
unitTests = internal.unitTests(),
isSpecRegEx = /.+spec.js/,
isSpec = function (unitTest) {
return isSpecRegEx.test(unitTest);
},
jasmine = _.filter(unitTests, isSpec),
jsUnity = _.reject(unitTests, isSpec);
result = runJSUnityTests(jsUnity) && runJasmineTests(jasmine, { format: jasmineReportFormat });
internal.setUnitTestsResult(result);
};
exports.runCommandLineTests = runCommandLineTests;