Version 1.5.6
- Fixed RangePartitionResolver.resolveForRead bug where it was not returning links due to a bad concat of results - Move compareFunction from Range class to RangePartitionResolver class
This commit is contained in:
Родитель
efa1e081ab
Коммит
59c1e06948
|
@ -1,8 +1,5 @@
|
|||
*.csproj
|
||||
*.njsproj
|
||||
generateDocs.cmd
|
||||
RunFunctionalTests.cmd
|
||||
runtests.cmd
|
||||
*.cmd
|
||||
|
||||
config.js
|
||||
.vs/
|
||||
|
|
|
@ -3,24 +3,24 @@
|
|||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{21b5837f-38c5-4c27-9cce-7dcb27eeda3f}</ProjectGuid>
|
||||
<ProjectGuid>{411c2c02-66ef-40c8-a964-af8fdacf3961}</ProjectGuid>
|
||||
<StartupFile>test\test.js</StartupFile>
|
||||
<WorkingDirectory>.</WorkingDirectory>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<StartWebBrowser>True</StartWebBrowser>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" />
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'" />
|
||||
<ItemGroup>
|
||||
<Content Include="package.json" />
|
||||
<Content Include="changelog.md" />
|
||||
<Content Include="readme.md" />
|
||||
<Content Include="readme.html" />
|
||||
<Content Include="test\readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -49,6 +49,15 @@
|
|||
<Compile Include="test\consistentHashRingTests.js">
|
||||
<TestFramework>Mocha</TestFramework>
|
||||
</Compile>
|
||||
<Compile Include="test\documentClientTests.js">
|
||||
<TestFramework>Mocha</TestFramework>
|
||||
</Compile>
|
||||
<Compile Include="test\rangeTests.js">
|
||||
<TestFramework>Mocha</TestFramework>
|
||||
</Compile>
|
||||
<Compile Include="test\rangePartitionResolverTests.js">
|
||||
<TestFramework>Mocha</TestFramework>
|
||||
</Compile>
|
||||
<Compile Include="test\murmurHashTests.js">
|
||||
<TestFramework>Mocha</TestFramework>
|
||||
</Compile>
|
||||
|
@ -59,29 +68,31 @@
|
|||
<None Include=".editorconfig" />
|
||||
<None Include=".eslintrc" />
|
||||
<None Include="package.json" />
|
||||
<None Include="readme.md" />
|
||||
<None Include="readme.html" />
|
||||
<None Include="changelog.md" />
|
||||
<None Include="test\readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="lib\" />
|
||||
<Folder Include="lib\hash\" />
|
||||
<Folder Include="lib" />
|
||||
<Folder Include="lib\hash" />
|
||||
<Folder Include="test" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
|
||||
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>0</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:39938/</IISUrl>
|
||||
<IISUrl>http://localhost:48022/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
|
@ -102,7 +113,7 @@
|
|||
</StartCmdLineArguments>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<EnableENC>True</EnableENC>
|
||||
<EnableENC>False</EnableENC>
|
||||
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "DocumentDB", "DocumentDB.njsproj", "{21B5837F-38C5-4C27-9CCE-7DCB27EEDA3F}"
|
||||
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "DocumentDB.Node.master", "DocumentDB.Node.master.njsproj", "{411C2C02-66EF-40C8-A964-AF8FDACF3961}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -11,10 +11,10 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{21B5837F-38C5-4C27-9CCE-7DCB27EEDA3F}.Debug|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{21B5837F-38C5-4C27-9CCE-7DCB27EEDA3F}.Debug|Any CPU.Build.0 = Release|Any CPU
|
||||
{21B5837F-38C5-4C27-9CCE-7DCB27EEDA3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{21B5837F-38C5-4C27-9CCE-7DCB27EEDA3F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{411C2C02-66EF-40C8-A964-AF8FDACF3961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{411C2C02-66EF-40C8-A964-AF8FDACF3961}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{411C2C02-66EF-40C8-A964-AF8FDACF3961}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{411C2C02-66EF-40C8-A964-AF8FDACF3961}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
|
@ -1,3 +1,8 @@
|
|||
## Changes in 1.5.6 : ##
|
||||
|
||||
- Fixed RangePartitionResolver.resolveForRead bug where it was not returning links due to a bad concat of results
|
||||
- Move compareFunction from Range class to RangePartitionResolver class
|
||||
|
||||
## Changes in 1.5.5 : ##
|
||||
|
||||
- Fixed hashParitionResolver resolveForRead(): When no partition key supplied was throwing exception, instead of returning a list of all registered links.
|
||||
|
|
|
@ -146,7 +146,7 @@ var Constants = {
|
|||
|
||||
CurrentVersion: "2015-08-06",
|
||||
|
||||
UserAgent: "documentdb-nodejs-sdk-1.5.5",
|
||||
UserAgent: "documentdb-nodejs-sdk-1.5.6",
|
||||
|
||||
DefaultPrecisions: {
|
||||
DefaultNumberHashPrecision: 3,
|
||||
|
|
|
@ -33,7 +33,6 @@ var Range = Base.defineClass(
|
|||
* @param {object} options - The Range constructor options.
|
||||
* @param {any} options.low - The low value in the range.
|
||||
* @param {any} options.high - The high value in the range.
|
||||
* @param {function} options.compareFunction - Optional function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.
|
||||
**/
|
||||
function(options) {
|
||||
if (options === undefined) {
|
||||
|
@ -50,80 +49,11 @@ var Range = Base.defineClass(
|
|||
}
|
||||
this.low = options.low;
|
||||
this.high = options.high;
|
||||
this.compareFunction = options.compareFunction;
|
||||
if (this.compareFunction !== undefined && typeof this.compareFunction !== "function") {
|
||||
throw new Error("Invalid argument: 'options.compareFunction' is not a function");
|
||||
}
|
||||
if (this._compare(this.low, this.high) > 0) {
|
||||
throw new Error("Invalid argument: 'options.low' must be less than or equal than 'options.high'");
|
||||
}
|
||||
Object.freeze(this);
|
||||
},
|
||||
{
|
||||
/**
|
||||
* Compares two ranges
|
||||
* @memberof Range
|
||||
* @instance
|
||||
* @param {object} other - The input range to be compared with this range.
|
||||
* @returns {number} - A negative value if this < other zero if this = other, or a positive value if this > other.
|
||||
**/
|
||||
compareTo: function(other) {
|
||||
if (this._compare(this.low, other.low) === 0 && this._compare(this.high, other.high) === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (this._compare(this.low, other.low) < 0 || this._compare(this.high, other.high) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check for containment of the other range in this range
|
||||
* @memberof Range
|
||||
* @instance
|
||||
* @param {object} other - The key or range to be checked if in this range.
|
||||
* @returns {boolean} - Returns true if the input is contained in this range; false otherwise.
|
||||
**/
|
||||
contains: function (other) {
|
||||
if (Range._isRange(other)) {
|
||||
return this._containsRange(other);
|
||||
}
|
||||
else {
|
||||
return this._containsPoint(other);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the other range intersects with this range.
|
||||
* @memberof Range
|
||||
* @instance
|
||||
* @param {object} other - The input range to be checked for intersection with this range.
|
||||
* @returns {boolean} - Returns true if the two ranges intersect with each other; false otherwise.
|
||||
**/
|
||||
intersect: function (other) {
|
||||
if (other === undefined || other === null) {
|
||||
throw new Error("Invalid Argument: 'other' is undefined or null");
|
||||
}
|
||||
var maxLow = this._compare(this.low, other.low) >= 0 ? this.low : other.low;
|
||||
var minHigh = this._compare(this.high, other.high) <= 0 ? this.high : other.high;
|
||||
if (this._compare(maxLow, minHigh) <= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts the range to a string in the form of "low,high"
|
||||
* @memberof Range
|
||||
* @instance
|
||||
* @returns {string} - Returns a string representation of the range.
|
||||
**/
|
||||
toString: function () {
|
||||
return String(this.low) + "," + String(this.high);
|
||||
},
|
||||
|
||||
/** @ignore */
|
||||
_compare: function (x, y) {
|
||||
_compare: function (x, y, compareFunction) {
|
||||
// Same semantics as Array.sort
|
||||
// http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare
|
||||
if (x === undefined && y === undefined)
|
||||
|
@ -132,8 +62,8 @@ var Range = Base.defineClass(
|
|||
return 1;
|
||||
if (y === undefined)
|
||||
return -1;
|
||||
if (this.compareFunction !== undefined) {
|
||||
var v = Number(this.compareFunction(x, y));
|
||||
if (compareFunction !== undefined) {
|
||||
var v = Number(compareFunction(x, y));
|
||||
if (v === NaN)
|
||||
return 0;
|
||||
return v;
|
||||
|
@ -148,16 +78,39 @@ var Range = Base.defineClass(
|
|||
},
|
||||
|
||||
/** @ignore */
|
||||
_containsPoint: function (point) {
|
||||
if (this._compare(point, this.low) >= 0 && this._compare(point, this.high) <= 0) {
|
||||
_contains: function (other, compareFunction) {
|
||||
if (Range._isRange(other)) {
|
||||
return this._containsRange(other, compareFunction);
|
||||
}
|
||||
else {
|
||||
return this._containsPoint(other, compareFunction);
|
||||
}
|
||||
},
|
||||
|
||||
/** @ignore */
|
||||
_containsPoint: function (point, compareFunction) {
|
||||
if (this._compare(point, this.low, compareFunction) >= 0 && this._compare(point, this.high, compareFunction) <= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/** @ignore */
|
||||
_containsRange: function (other) {
|
||||
if (this._compare(other.low, this.low) >= 0 && this._compare(other.high, this.high) <= 0) {
|
||||
_containsRange: function (other, compareFunction) {
|
||||
if (this._compare(other.low, this.low, compareFunction) >= 0 && this._compare(other.high, this.high, compareFunction) <= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/** @ignore */
|
||||
_intersect: function (other, compareFunction) {
|
||||
if (other === undefined || other === null) {
|
||||
throw new Error("Invalid Argument: 'other' is undefined or null");
|
||||
}
|
||||
var maxLow = this._compare(this.low, other.low, compareFunction) >= 0 ? this.low : other.low;
|
||||
var minHigh = this._compare(this.high, other.high, compareFunction) <= 0 ? this.high : other.high;
|
||||
if (this._compare(maxLow, minHigh, compareFunction) <= 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -180,6 +133,11 @@ var Range = Base.defineClass(
|
|||
this._state = this._states.ended;
|
||||
callback(undefined, this.resources, this.resHeaders);
|
||||
}
|
||||
},
|
||||
|
||||
/** @ignore */
|
||||
_toString: function () {
|
||||
return String(this.low) + "," + String(this.high);
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -206,8 +164,9 @@ var RangePartitionResolver = Base.defineClass(
|
|||
* @param {string | function} partitionKeyExtractor - If partitionKeyExtractor is a string, it should be the name of the property in the document to execute the hashing on.
|
||||
* If partitionKeyExtractor is a function, it should be a function to extract the partition key from an object.
|
||||
* @param {Array} partitionKeyMap - The map from Range to collection link that is used for partitioning requests.
|
||||
* @param {function} compareFunction - Optional function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.
|
||||
**/
|
||||
function(partitionKeyExtractor, partitionKeyMap) {
|
||||
function(partitionKeyExtractor, partitionKeyMap, compareFunction) {
|
||||
if (partitionKeyExtractor === undefined || partitionKeyExtractor === null) {
|
||||
throw new Error("partitionKeyExtractor cannot be null or undefined");
|
||||
}
|
||||
|
@ -241,8 +200,13 @@ var RangePartitionResolver = Base.defineClass(
|
|||
if (!allMapEntriesAreValid) {
|
||||
throw new Error("All partitionKeyMap entries have to be a tuple {range: Range, link: string }");
|
||||
}
|
||||
if (compareFunction !== undefined && typeof compareFunction !== "function") {
|
||||
throw new Error("Invalid argument: 'compareFunction' is not a function");
|
||||
}
|
||||
|
||||
this.partitionKeyExtractor = partitionKeyExtractor;
|
||||
this.partitionKeyMap = partitionKeyMap;
|
||||
this.compareFunction = compareFunction;
|
||||
}, {
|
||||
/**
|
||||
* Extracts the partition key from the specified document using the partitionKeyExtractor
|
||||
|
@ -274,7 +238,7 @@ var RangePartitionResolver = Base.defineClass(
|
|||
if (mapEntry !== undefined && mapEntry !== null) {
|
||||
return mapEntry.link;
|
||||
}
|
||||
throw new Error("Invalid operation: A containing range for '" + range.toString() + "' doesn't exist in the partition map.");
|
||||
throw new Error("Invalid operation: A containing range for '" + range._toString() + "' doesn't exist in the partition map.");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -295,7 +259,8 @@ var RangePartitionResolver = Base.defineClass(
|
|||
|
||||
/** @ignore */
|
||||
_getFirstContainingMapEntryOrNull: function (point) {
|
||||
var containingMapEntries = this.partitionKeyMap.filter(function (p) { return p.range !== undefined && p.range.contains(point); });
|
||||
var _this = this;
|
||||
var containingMapEntries = this.partitionKeyMap.filter(function (p) { return p.range !== undefined && p.range._contains(point, _this.compareFunction); });
|
||||
if (containingMapEntries && containingMapEntries.length > 0) {
|
||||
return containingMapEntries[0];
|
||||
}
|
||||
|
@ -306,10 +271,12 @@ var RangePartitionResolver = Base.defineClass(
|
|||
_getIntersectingMapEntries: function (partitionKey) {
|
||||
var _this = this;
|
||||
var partitionKeys = (partitionKey instanceof Array) ? partitionKey : [partitionKey];
|
||||
var ranges = partitionKeys.map(function (p) { return Range._isRange(p) ? p : new Range(p); });
|
||||
var ranges = partitionKeys.map(function (p) { return Range._isRange(p) ? p : new Range({ low: p }); });
|
||||
var result = new Array();
|
||||
ranges.forEach(function (range) {
|
||||
result.concat(_this.partitionKeyMap.filter(function (entry) { return entry.range.intersect(range); }));
|
||||
result = result.concat(_this.partitionKeyMap.filter(function (entry) {
|
||||
return entry.range._intersect(range, _this.compareFunction);
|
||||
}));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"database",
|
||||
"cloud"
|
||||
],
|
||||
"version": "1.5.5",
|
||||
"version": "1.5.6",
|
||||
"author": "Microsoft Corporation",
|
||||
"main": "./index.js",
|
||||
"engine": {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Windows Azure DocumentDB SDK: node.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Windows Azure DocumentDB Node.js SDK</h1>
|
||||
<p>
|
||||
This project provides a node module that makes it easy to interact with Azure DocumentDB. For documentation please see the <a href="https://azure.microsoft.com/en-us/documentation/articles/documentdb-sdk-node/" target="_blank">Microsoft Azure DocumentDB Node.js SDK Documentation</a>.
|
||||
</p>
|
||||
<h2>Installation</h2><h4>Core Module</h4><p>The core module uses the callbacks model for responses, exposed through the DocumentClient </p>
|
||||
<pre class="prettyprint source"><code>npm install documentdb</code></pre>
|
||||
<h2>Usage</h2>
|
||||
<p>To use this SDK to call Azure DocumentDB, you need to first <a href="http://azure.microsoft.com/en-us/documentation/articles/documentdb-create-account/" target="_blank">create an account</a>.</p>
|
||||
<p>You can follow this <a href="http://azure.microsoft.com/en-us/documentation/articles/documentdb-nodejs-application/" target="_blank">tutorial</a> to help you get started.</p>
|
||||
<h2>Examples</h2><h4>Hello World using Callbacks via the Core Module</h4><pre class="prettyprint source lang-js"><code>var DocumentClient = require('documentdb').DocumentClient;
|
||||
var host = "[hostendpoint]"; // Add your endpoint
|
||||
var masterKey = "[database account masterkey]"; // Add the massterkey of the endpoint
|
||||
var client = new DocumentClient(host, {masterKey: masterKey});
|
||||
var databaseDefinition = { id: "sample database" };
|
||||
var collectionDefinition = { id: "sample collection" };
|
||||
var documentDefinition = { id: "hello world doc", content: "Hello World!" };
|
||||
client.createDatabase(databaseDefinition, function(err, database) {
|
||||
if(err) return console.log(err);
|
||||
console.log('created db');
|
||||
client.createCollection(database._self, collectionDefinition, function(err, collection) {
|
||||
if(err) return console.log(err);
|
||||
console.log('created collection');
|
||||
client.createDocument(collection._self, documentDefinition, function(err, document) {
|
||||
if(err) return console.log(err);
|
||||
console.log('Created Document with content: ', document.content);
|
||||
cleanup(client, database);
|
||||
});
|
||||
});
|
||||
});
|
||||
function cleanup(client, database) {
|
||||
client.deleteDatabase(database._self, function(err) {
|
||||
if(err) console.log(err);
|
||||
})
|
||||
}</code></pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Windows Azure DocumentDB SDK: node.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Windows Azure DocumentDB nodejs SDK</h2>
|
||||
<p>
|
||||
DocumentDB is a purpose built NoSQL JSON document database designed for modern mobile and web applications. DocumentDB supports rich queries over JSON data as well as, <br>
|
||||
transactional execution of JavaScript based application logic. DocumentDB is built with a deep commitment to the JSON data model enabling it to offer differentiated query and data <br>
|
||||
processing capabilities that scale to meet the needs of the most demanding modern applications.
|
||||
</p>
|
||||
<p>
|
||||
The Nodejs sdk uses callbacks model for responses and this is exposed in DocumentClient <br>
|
||||
</p>
|
||||
<h4>Installing the library using npm</h4>
|
||||
<p><pre>> npm install documentdb</pre></p>
|
||||
<h4>Hello world example code using callbacks</h4>
|
||||
<p><pre style="background-color:#eee">
|
||||
|
||||
var DocumentClient = require('documentdb').DocumentClient;
|
||||
|
||||
var host = [hostendpoint]; // Add your endpoint
|
||||
var masterKey = [database account masterkey]; // Add the massterkey of the endpoint
|
||||
|
||||
var client = new DocumentClient(host, {masterKey: masterKey});
|
||||
var databaseDefinition = { id: "sample database" };
|
||||
var collectionDefinition = { id: "sample collection" };
|
||||
var documentDefinition = { id: "hello world doc", content: "Hello World!" };
|
||||
|
||||
client.createDatabase(databaseDefinition, function(err, database) {
|
||||
if(err) return console.log(err);
|
||||
console.log('created db');
|
||||
|
||||
client.createCollection(database._self, collectionDefinition, function(err, collection) {
|
||||
if(err) return console.log(err);
|
||||
|
||||
console.log('created collection');
|
||||
|
||||
client.createDocument(collection._self, documentDefinition, function(err, document) {
|
||||
if(err) return console.log(err);
|
||||
|
||||
console.log('Created Document with content: ', document.content);
|
||||
cleanup(client, database);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function cleanup(client, database) {
|
||||
client.deleteDatabase(database._self, function(err) {
|
||||
if(err) console.log(err);
|
||||
})
|
||||
}
|
||||
</pre></p>
|
||||
|
||||
##Community
|
||||
- [DoQmentDB](https://github.com/a8m/doqmentdb) - A Promise-based DocumentDB client for MongoDB users
|
|
@ -24,7 +24,7 @@ SOFTWARE.
|
|||
"use strict";
|
||||
|
||||
var assert = require("assert");
|
||||
var ConsistentHashRing = require("../lib/Hash/consistentHashRing").ConsistentHashRing;
|
||||
var ConsistentHashRing = require("../lib/hash/consistentHashRing").ConsistentHashRing;
|
||||
|
||||
describe("ConsistentHashRing new()", function () {
|
||||
it("valid arguments does not throw", function () {
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var lib = require("../lib/"),
|
||||
testConfig = require("./_testConfig"),
|
||||
assert = require("assert");
|
||||
|
||||
var DocumentClient = lib.DocumentClient,
|
||||
Constants = lib.Constants;
|
||||
|
||||
describe("DocumentClient Tests", function () {
|
||||
var host = testConfig.host;
|
||||
var masterKey = testConfig.masterKey;
|
||||
var client = new DocumentClient(host, { masterKey: masterKey });
|
||||
|
||||
describe("setIsUpsertHeader", function () {
|
||||
it("Should add is-upsert header.", function (done) {
|
||||
var headers = client.defaultHeaders;
|
||||
assert.equal(undefined, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
client.setIsUpsertHeader(headers);
|
||||
assert.equal(true, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should update is-upsert header.", function (done) {
|
||||
var headers = {};
|
||||
headers[Constants.HttpHeaders.IsUpsert] = false;
|
||||
assert.equal(false, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
client.setIsUpsertHeader(headers);
|
||||
assert.equal(true, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should throw on undefined headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(); },
|
||||
/The "headers" parameter must not be null or undefined/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should throw on null headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(null); },
|
||||
/The "headers" parameter must not be null or undefined/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should throw on invalid string headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(""); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "string"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should throw on invalid number headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(0); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "number"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("Should throw on invalid boolean headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(false); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "boolean"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sprintf", function () {
|
||||
it("0 strings", function (done) {
|
||||
assert.equal("foo", client.sprintf("foo"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("1 string", function (done) {
|
||||
assert.equal("foo", client.sprintf("%s", "foo"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("2 strings", function (done) {
|
||||
assert.equal("foobar", client.sprintf("%s%s", "foo", "bar"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("3 strings", function (done) {
|
||||
assert.equal("foobarbaz", client.sprintf("%s%s%s", "foo", "bar", "baz"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("%% escapes", function (done) {
|
||||
assert.equal('%s', client.sprintf("%%s", 'foo'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("validateOptionsAndCallback Unit Tests", function () {
|
||||
it("no parameters", function (done) {
|
||||
var result = client.validateOptionsAndCallback();
|
||||
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal(undefined, result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("options", function (done) {
|
||||
var result = client.validateOptionsAndCallback({});
|
||||
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal(undefined, result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(function () { });
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("options, callback.", function (done) {
|
||||
var result = client.validateOptionsAndCallback({}, function () { });
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("undefined, callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(undefined, function () { });
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("null, callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(null, function () { });
|
||||
assert.equal(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
it("invalid string options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback("foo", function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid number options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback(0, function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "number"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid bool options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback(false, function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "boolean"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid string callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, "bar"); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid number callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, 0); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "number"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid boolean callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, false); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "boolean"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid options, invalid callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback("foo", "bar"); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -24,7 +24,7 @@ SOFTWARE.
|
|||
"use strict";
|
||||
|
||||
var assert = require("assert");
|
||||
var HashPartitionResolver = require("../lib/Hash/hashPartitionResolver").HashPartitionResolver;
|
||||
var HashPartitionResolver = require("../lib/hash/hashPartitionResolver").HashPartitionResolver;
|
||||
|
||||
describe("HashPartitionResolver new()", function () {
|
||||
it(" does not throw", function () {
|
||||
|
|
|
@ -23,7 +23,7 @@ SOFTWARE.
|
|||
|
||||
"use strict";
|
||||
|
||||
var MurmurHash = require("../lib/Hash/murmurHash").MurmurHash;
|
||||
var MurmurHash = require("../lib/hash/murmurHash").MurmurHash;
|
||||
var assert = require("assert")
|
||||
|
||||
describe("MurmurHash.hash", function () {
|
||||
|
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var lib = require("../lib/"),
|
||||
assert = require("assert");
|
||||
|
||||
var Range = lib.Range,
|
||||
RangePartitionResolver = lib.RangePartitionResolver;
|
||||
|
||||
describe("RangePartitionResolver", function () {
|
||||
describe("constructor", function () {
|
||||
it("missing partitionKeyExtractor throws", function (done) {
|
||||
var expetcedError = /Error: partitionKeyExtractor cannot be null or undefined/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver();
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(undefined);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(null);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid partitionKeyExtractor throws", function (done) {
|
||||
var expetcedError = /partitionKeyExtractor must be either a 'string' or a 'function'/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(0);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = RangePartitionResolver(true);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(NaN);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver([]);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver({});
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("missing partitionKeyMap throws", function (done) {
|
||||
var expectedError = /Error: partitionKeyMap cannot be null or undefined/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("");
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(function () {
|
||||
});
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", null);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("invalid partitionKeyMap throws", function (done) {
|
||||
var expectedError = /Error: partitionKeyMap has to be an Array/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", 0);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", "");
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", true);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", NaN);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", {});
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
var r = new RangePartitionResolver("", new Array());
|
||||
done();
|
||||
});
|
||||
|
||||
it("valid RangePartitionResolver", function (done) {
|
||||
var resolver = new RangePartitionResolver("", []);
|
||||
assert(resolver);
|
||||
assert.strictEqual(resolver.partitionKeyExtractor, "");
|
||||
assert.deepEqual(resolver.partitionKeyMap, []);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_getFirstContainingMapEntryOrNull", function () {
|
||||
it("_getFirstContainingMapEntryOrNull - empty map returns null", function (done) {
|
||||
var ranges = [undefined, null, 0, "", true, [], {}, NaN, new Range()];
|
||||
var resolver = new RangePartitionResolver("", []);
|
||||
ranges.forEach(function (r) {
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(r);
|
||||
assert.equal(result, null);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it("_tryGetContainingRange - map with no containing entry returns null", function (done) {
|
||||
var mapEntry = { range: new Range({ low: "A" }), link: "link1" };
|
||||
var resolver = new RangePartitionResolver("key", [mapEntry]);
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(new Range({ low: "B" }));
|
||||
assert.equal(result, null);
|
||||
done();
|
||||
});
|
||||
|
||||
it("_tryGetContainingRange - map with single containing entry returns entry", function (done) {
|
||||
var mapEntry = { range: new Range(), link: "link1" };
|
||||
var resolver = new RangePartitionResolver("key", [mapEntry]);
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(new Range());
|
||||
assert.deepEqual(result, { range: new Range(), link: "link1" });
|
||||
done();
|
||||
});
|
||||
|
||||
it("_tryGetContainingRange - map with more multiple containing entries returns first entry", function (done) {
|
||||
var map1 = [
|
||||
{ range: new Range({ low: "A", high: "B" }), link: "link1" },
|
||||
{ range: new Range({ low: "A" }), link: "link2" }
|
||||
];
|
||||
|
||||
var resolver1 = new RangePartitionResolver("key", map1);
|
||||
var result1 = resolver1._getFirstContainingMapEntryOrNull(new Range({ low: "A" }));
|
||||
assert.strictEqual(result1.link, "link1");
|
||||
|
||||
var map2 = [
|
||||
{ range: new Range({ low: "A" }), link: "link2" },
|
||||
{ range: new Range({ low: "A", high: "Z" }), link: "link1" }
|
||||
];
|
||||
|
||||
var resolver2 = new RangePartitionResolver("key", map2);
|
||||
var result2 = resolver2._getFirstContainingMapEntryOrNull(new Range({ low: "A" }));
|
||||
assert.strictEqual(result2.link, "link2");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveForCreate", function () {
|
||||
it("_tryGetContainingRange - map containing parition key returns corresponding link", function (done) {
|
||||
var resolver = new RangePartitionResolver("key", [
|
||||
{ range: new Range({ low: "A", high: "M" }), link: "link1" },
|
||||
{ range: new Range({ low: "N", high: "Z" }), link: "link2" }
|
||||
]);
|
||||
var result = resolver.resolveForCreate("X");
|
||||
assert.strictEqual(result, "link2");
|
||||
done();
|
||||
});
|
||||
|
||||
it("_tryGetContainingRange - map not containing parition key throws", function (done) {
|
||||
var resolver = new RangePartitionResolver("key", [
|
||||
{ range: new Range({ low: "A", high: "M" }), link: "link1" }
|
||||
]);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var result = resolver.resolveForCreate("X");
|
||||
},
|
||||
/Error: Invalid operation: A containing range for 'X,X' doesn't exist in the partition map./
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
var resolveForReadTest = function (resolver, partitionKey, expectedLinks) {
|
||||
var result = resolver.resolveForRead(partitionKey);
|
||||
assert.deepEqual(expectedLinks, result);
|
||||
};
|
||||
|
||||
describe("resolveForRead", function () {
|
||||
var resolver = new RangePartitionResolver(
|
||||
function (doc) {
|
||||
return doc.key;
|
||||
},
|
||||
[
|
||||
{
|
||||
range: new Range({ low: "A", high: "M" }),
|
||||
link: "link1"
|
||||
},
|
||||
{
|
||||
range: new Range({ low: "N", high: "Z" }),
|
||||
link: "link2"
|
||||
}
|
||||
]);
|
||||
|
||||
it("undefined", function (done) {
|
||||
var partitionKey = undefined;
|
||||
var expectedLinks = ["link1", "link2"];
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
|
||||
it("null", function (done) {
|
||||
var partitionKey = null;
|
||||
var expectedLinks = ["link1", "link2"];
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveForRead string", function () {
|
||||
var resolver = new RangePartitionResolver(
|
||||
function (doc) {
|
||||
return doc.key;
|
||||
},
|
||||
[
|
||||
{
|
||||
range: new Range({ low: "A", high: "M" }),
|
||||
link: "link1"
|
||||
},
|
||||
{
|
||||
range: new Range({ low: "N", high: "Z" }),
|
||||
link: "link2"
|
||||
}
|
||||
]);
|
||||
|
||||
it("point", function (done) {
|
||||
var partitionKey = new Range({ low: "D" });
|
||||
var expectedLinks = ["link1"];
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
|
||||
var partitionKey2 = new Range({ low: "Q" });
|
||||
var expectedLinks2 = ["link2"];
|
||||
resolveForReadTest(resolver, partitionKey2, expectedLinks2);
|
||||
done();
|
||||
});
|
||||
|
||||
it("range", function (done) {
|
||||
var partitionKey = new Range({ low: "D", high: "Q" });
|
||||
var expectedLinks = ["link1", "link2"];
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
|
||||
it("array of ranges", function (done) {
|
||||
var partitionKey = [
|
||||
new Range({ low: "A", high: "B" }),
|
||||
new Range({ low: "Q" })
|
||||
];
|
||||
var expectedLinks = ["link1", "link2"];
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveForRead number", function () {
|
||||
var partitionKeyExtractor = function (doc) {
|
||||
return doc.key;
|
||||
};
|
||||
|
||||
var partitionKeyMap = [
|
||||
{
|
||||
range: new Range({ low: 1, high: 15 }),
|
||||
link: "link1"
|
||||
},
|
||||
{
|
||||
range: new Range({ low: 16, high: 30 }),
|
||||
link: "link2"
|
||||
}
|
||||
];
|
||||
|
||||
it("point, default compareFunction", function (done) {
|
||||
var resolver = new RangePartitionResolver(partitionKeyExtractor, partitionKeyMap);
|
||||
|
||||
var partitionKey = new Range({ low: 2 });
|
||||
var expectedLinks = ["link2"];
|
||||
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
|
||||
it("point, custom compareFunction", function (done) {
|
||||
var resolver = new RangePartitionResolver(partitionKeyExtractor, partitionKeyMap, function (a, b) {
|
||||
return a - b;
|
||||
});
|
||||
|
||||
var partitionKey = new Range({ low: 2 });
|
||||
var expectedLinks = ["link1"];
|
||||
|
||||
resolveForReadTest(resolver, partitionKey, expectedLinks);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("compareFunction", function () {
|
||||
var invalidCompareFunctionTest = function (compareFunction, done) {
|
||||
assert.throws(
|
||||
function () {
|
||||
var resolver = new RangePartitionResolver(
|
||||
"key",
|
||||
[{ range: new Range({ low: "A" }), link: "link1" }],
|
||||
compareFunction
|
||||
);
|
||||
},
|
||||
/Invalid argument: 'compareFunction' is not a function/);
|
||||
done();
|
||||
}
|
||||
|
||||
it("invalid compareFunction - null", function (done) {
|
||||
var compareFunction = null;
|
||||
invalidCompareFunctionTest(compareFunction, done);
|
||||
});
|
||||
|
||||
it("invalid compareFunction - string", function (done) {
|
||||
var compareFunction = "";
|
||||
invalidCompareFunctionTest(compareFunction, done);
|
||||
});
|
||||
|
||||
it("invalid compareFunction - number", function (done) {
|
||||
var compareFunction = 0;
|
||||
invalidCompareFunctionTest(compareFunction, done);
|
||||
});
|
||||
|
||||
it("invalid compareFunction - boolean", function (done) {
|
||||
var compareFunction = false;
|
||||
invalidCompareFunctionTest(compareFunction, done);
|
||||
});
|
||||
|
||||
it("invalid compareFunction - object", function (done) {
|
||||
var compareFunction = {};
|
||||
invalidCompareFunctionTest(compareFunction, done);
|
||||
});
|
||||
|
||||
it("compareFunction throws", function (done) {
|
||||
var resolver = new RangePartitionResolver(
|
||||
"key",
|
||||
[{ range: new Range({ low: "A" }), link: "link1" }],
|
||||
function (a, b) { throw new Error("Compare error"); }
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var result = resolver.resolveForRead("A", ["link1"]);
|
||||
},
|
||||
/Error: Compare error/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var lib = require("../lib/"),
|
||||
assert = require("assert");
|
||||
|
||||
var Range = lib.Range;
|
||||
|
||||
describe("Range Tests", function () {
|
||||
describe("constructor", function () {
|
||||
var invalidOptionsTest = function (options, expectedError, done) {
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new Range(options);
|
||||
},
|
||||
expectedError);
|
||||
done();
|
||||
}
|
||||
|
||||
var optionsIsNullTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options' is null/, done);
|
||||
}
|
||||
|
||||
var optionsIsNotAnObjectTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options' is not an object/, done);
|
||||
}
|
||||
|
||||
var invalidRangeTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options.low' must be less than or equal than 'options.high'/, done);
|
||||
}
|
||||
|
||||
it("options - undefined (ommited argument)", function (done) {
|
||||
assert(new Range());
|
||||
done();
|
||||
});
|
||||
|
||||
it("options - undefined (literal argument)", function (done) {
|
||||
assert(new Range(undefined));
|
||||
done();
|
||||
});
|
||||
|
||||
it("options - null ", function (done) {
|
||||
var options = null;
|
||||
optionsIsNullTest(options, done);
|
||||
});
|
||||
|
||||
it("options - number", function (done) {
|
||||
var options = 0;
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("invalid options - string", function (done) {
|
||||
var options = "";
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("invalid options - boolean", function (done) {
|
||||
var options = false;
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("Range instances are frozen", function (done) {
|
||||
var r = new Range();
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
r.compareFunction = 1;
|
||||
},
|
||||
/Can't add property compareFunction, object is not extensible/
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_contains", function () {
|
||||
it("undefined,undefined contains undefined is true", function (done) {
|
||||
var r = new Range();
|
||||
assert(r._contains(undefined));
|
||||
done();
|
||||
});
|
||||
|
||||
it("undefined,undefined contains null is false", function (done) {
|
||||
var r = new Range();
|
||||
assert(!r._contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("null,null contains undefined is true", function (done) {
|
||||
var r = new Range({ low: null });
|
||||
assert(r._contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("null,null contains null is true", function (done) {
|
||||
var r = new Range({ low: null });
|
||||
assert(r._contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("range contains self is true - default range", function (done) {
|
||||
var r = new Range();
|
||||
assert(r._contains(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("range contains self is true - non-default range", function (done) {
|
||||
var r = new Range({ low: "A" });
|
||||
assert(r._contains(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,D contains B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "D" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,C contains A,D is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "D" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,C contains B,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
var r2 = new Range({ low: "B", high: "D" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,D contains A,C is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "C" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,B contains B,C is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,C contains A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,B contains C,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "C", high: "D" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("C,D contains A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "C", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1._contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,C contains B is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
assert(r1._contains("B"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,C contains A is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
assert(!r1._contains("A"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,B contains C is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1._contains("C"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_containsPoint", function () {
|
||||
var range = new Range({ low: 1, high: 3 });
|
||||
|
||||
it("numbers, default comparison", function (done) {
|
||||
assert(range._containsPoint(20));
|
||||
done();
|
||||
});
|
||||
|
||||
it("numbers, custom comparison", function (done) {
|
||||
|
||||
assert(!range._containsPoint(20, function (a, b) {
|
||||
return a - b;
|
||||
}));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_containsRange", function () {
|
||||
var range = new Range({ low: 1, high: 3 });
|
||||
|
||||
it("numbers, default comparison", function (done) {
|
||||
assert(range._containsRange({ low: 20, high: 29}));
|
||||
done();
|
||||
});
|
||||
|
||||
it("numbers, custom comparison", function (done) {
|
||||
assert(!range._containsRange({ low: 20, high: 29 }, function (a, b) {
|
||||
return a - b;
|
||||
}));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_intersect", function () {
|
||||
var otherIsUndefinedOrNullTest = function (other, done) {
|
||||
var r = new Range();
|
||||
assert.throws(
|
||||
function () {
|
||||
r._intersect(other);
|
||||
},
|
||||
/Invalid Argument: 'other' is undefined or null/
|
||||
);
|
||||
done();
|
||||
};
|
||||
|
||||
it("error - other is undefined", function (done) {
|
||||
otherIsUndefinedOrNullTest(undefined, done);
|
||||
});
|
||||
|
||||
it("error - other is null", function (done) {
|
||||
otherIsUndefinedOrNullTest(null, done);
|
||||
});
|
||||
|
||||
it("range intersect self is true - default range", function (done) {
|
||||
var r = new Range();
|
||||
assert(r._intersect(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("R intersect R is true - non default range", function (done) {
|
||||
var r = new Range({ low: 1, high: "2" });
|
||||
assert(r._intersect(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,D insersects B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "D" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,C insersects A,D is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "D" });
|
||||
assert(r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,C insersects B,D is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
var r2 = new Range({ low: "B", high: "D" });
|
||||
assert(r1._intersect(r2));
|
||||
assert(r2._intersect(r1));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,D insersects A,C is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "C" });
|
||||
assert(r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,B insersects B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1._intersect(r2));
|
||||
assert(r2._intersect(r1));
|
||||
done();
|
||||
});
|
||||
|
||||
it("B,C insersects A,B is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("A,B insersects C,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "C", high: "D" });
|
||||
assert(!r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("C,D insersects A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "C", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1._intersect(r2));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_toString", function () {
|
||||
var toStringTest = function (options, expectedString, done) {
|
||||
var r = new Range(options);
|
||||
assert.strictEqual(r._toString(), expectedString);
|
||||
done();
|
||||
};
|
||||
|
||||
it("undefined values", function (done) {
|
||||
toStringTest(undefined, "undefined,undefined", done);
|
||||
});
|
||||
it("null values", function (done) {
|
||||
toStringTest({ low: null }, "null,null", done);
|
||||
});
|
||||
it("NaN values", function (done) {
|
||||
toStringTest({ low: NaN }, "NaN,NaN", done);
|
||||
});
|
||||
it("number values", function (done) {
|
||||
toStringTest({ low: 1 }, "1,1", done);
|
||||
});
|
||||
it("string values", function (done) {
|
||||
toStringTest({ low: "a" }, "a,a", done);
|
||||
});
|
||||
it("boolean values", function (done) {
|
||||
toStringTest({ low: false, high: true }, "false,true", done);
|
||||
});
|
||||
it("object values", function (done) {
|
||||
toStringTest({ low: {} }, "[object Object],[object Object]", done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_compare", function () {
|
||||
var r = new Range();
|
||||
|
||||
var compareAsNumbers = function (a, b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
var constantCompareFunction = function (a, b) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
it("(undefined, undefined) === 0", function (done) {
|
||||
assert(r._compare() === 0);
|
||||
assert(r._compare(undefined) === 0);
|
||||
assert(r._compare(undefined, undefined) === 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("(undefined, y) > 0", function (done) {
|
||||
assert(r._compare(undefined, null) > 0);
|
||||
assert(r._compare(undefined, -NaN) > 0);
|
||||
assert(r._compare(undefined, 0) > 0);
|
||||
assert(r._compare(undefined, NaN) > 0);
|
||||
assert(r._compare(undefined, true) > 0);
|
||||
assert(r._compare(undefined, false) > 0);
|
||||
assert(r._compare(undefined, "a") > 0);
|
||||
assert(r._compare(undefined, "undefined") > 0);
|
||||
assert(r._compare(undefined, "z") > 0);
|
||||
assert(r._compare(undefined, []) > 0);
|
||||
assert(r._compare(undefined, {}) > 0);
|
||||
assert(r._compare(undefined, 2, constantCompareFunction) > 0);
|
||||
assert(r._compare(undefined, 2, compareAsNumbers) > 0);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("(x, undefined) < 0", function (done) {
|
||||
assert(r._compare(null) < 0);
|
||||
assert(r._compare(-NaN) < 0);
|
||||
assert(r._compare(0) < 0);
|
||||
assert(r._compare(NaN) < 0);
|
||||
assert(r._compare(true) < 0);
|
||||
assert(r._compare(false) < 0);
|
||||
assert(r._compare("a") < 0);
|
||||
assert(r._compare("undefined") < 0);
|
||||
assert(r._compare("z") < 0);
|
||||
assert(r._compare([]) < 0);
|
||||
assert(r._compare({}) < 0);
|
||||
assert(r._compare(1, undefined, constantCompareFunction) < 0);
|
||||
assert(r._compare(1, undefined, compareAsNumbers) < 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("values as strings (default)", function (done) {
|
||||
assert(r._compare("A", "B") < 0);
|
||||
assert(r._compare("", "") === 0);
|
||||
assert(r._compare("B", "A") > 0);
|
||||
assert(r._compare("10", "2") < 0);
|
||||
assert(r._compare(10, "02") > 0);
|
||||
assert(r._compare(10, 2) < 0);
|
||||
assert(r._compare(null, "nulm") < 0);
|
||||
assert(r._compare(null, "null") === 0);
|
||||
assert(r._compare(null, "nulk") > 0);
|
||||
assert(r._compare(true, "truf") < 0);
|
||||
assert(r._compare(true, "true") === 0);
|
||||
assert(r._compare(true, "trud") > 0);
|
||||
assert(r._compare({}, "[object Object]") === 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("values as numbers", function (done) {
|
||||
|
||||
assert(r._compare(undefined, 2, compareAsNumbers) > 0);
|
||||
assert(r._compare(1, 2, compareAsNumbers) < 0);
|
||||
assert(r._compare(0, 0, compareAsNumbers) === 0);
|
||||
assert(r._compare(10, 2, compareAsNumbers) > 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("always return 0", function (done) {
|
||||
assert(r._compare(1, 2, constantCompareFunction) === 0);
|
||||
assert(r._compare(2, 1, constantCompareFunction) === 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_isRange", function () {
|
||||
it("_isRange(undefined) is false", function (done) {
|
||||
assert(!Range._isRange());
|
||||
done();
|
||||
});
|
||||
|
||||
it("_isRange(null) is false", function (done) {
|
||||
assert(!Range._isRange(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("_isRange(non-object) is false", function (done) {
|
||||
var points = [
|
||||
undefined,
|
||||
null,
|
||||
1,
|
||||
"",
|
||||
true,
|
||||
NaN,
|
||||
function () {
|
||||
},
|
||||
{},
|
||||
{
|
||||
low: ""
|
||||
}
|
||||
];
|
||||
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
assert(!Range._isRange(points[i]));
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("_isRange(point) is false", function (done) {
|
||||
var ranges = [
|
||||
{
|
||||
low: "",
|
||||
high: 1
|
||||
},
|
||||
new Range()
|
||||
];
|
||||
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
assert(Range._isRange(ranges[i]));
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -23,16 +23,18 @@ SOFTWARE.
|
|||
|
||||
"use strict";
|
||||
|
||||
var Base = require("documentdb").Base
|
||||
, DocumentDBClient = require("documentdb").DocumentClient
|
||||
, DocumentBase = require("documentdb").DocumentBase
|
||||
, Constants = require("documentdb").Constants
|
||||
, assert = require("assert")
|
||||
, testConfig = require("./_testConfig")
|
||||
, Stream = require("stream")
|
||||
, Range = require("documentdb").Range
|
||||
, RangePartitionResolver = require("documentdb").RangePartitionResolver
|
||||
, HashPartitionResolver = require("documentdb").HashPartitionResolver;
|
||||
var lib = require("../lib/"),
|
||||
assert = require("assert"),
|
||||
testConfig = require("./_testConfig"),
|
||||
Stream = require("stream");
|
||||
|
||||
var Base = lib.Base,
|
||||
DocumentDBClient = lib.DocumentClient,
|
||||
DocumentBase = lib.DocumentBase,
|
||||
Constants = lib.Constants,
|
||||
Range = lib.Range,
|
||||
RangePartitionResolver = lib.RangePartitionResolver,
|
||||
HashPartitionResolver = lib.HashPartitionResolver;
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
|
||||
|
@ -2285,951 +2287,7 @@ describe("NodeJS CRUD Tests", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("setIsUpsertHeader Unit Tests", function () {
|
||||
var client = new DocumentDBClient(host, { masterKey: masterKey });
|
||||
|
||||
it("[nativeApi] Should add is-upsert header.", function (done) {
|
||||
var headers = client.defaultHeaders;
|
||||
assert.equal(undefined, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
client.setIsUpsertHeader(headers);
|
||||
assert.equal(true, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should update is-upsert header.", function (done) {
|
||||
var headers = {};
|
||||
headers[Constants.HttpHeaders.IsUpsert] = false;
|
||||
assert.equal(false, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
client.setIsUpsertHeader(headers);
|
||||
assert.equal(true, headers[Constants.HttpHeaders.IsUpsert]);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should throw on undefined headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(); },
|
||||
/The "headers" parameter must not be null or undefined/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should throw on null headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(null); },
|
||||
/The "headers" parameter must not be null or undefined/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should throw on invalid string headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(""); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "string"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should throw on invalid number headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(0); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "number"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Should throw on invalid boolean headers", function (done) {
|
||||
assert.throws(
|
||||
function () { client.setIsUpsertHeader(false); },
|
||||
/The "headers" parameter must be an instance of "Object". Actual type is: "boolean"./
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("validateOptionsAndCallback Unit Tests", function () {
|
||||
var client = new DocumentDBClient(host, { masterKey: masterKey });
|
||||
|
||||
it("[nativeApi] no parameters", function (done) {
|
||||
var result = client.validateOptionsAndCallback();
|
||||
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal(undefined, result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] options", function (done) {
|
||||
var result = client.validateOptionsAndCallback({});
|
||||
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal(undefined, result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(function(){});
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] options, callback.", function (done) {
|
||||
var result = client.validateOptionsAndCallback({}, function(){});
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] undefined, callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(undefined, function(){});
|
||||
assert.notEqual(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] null, callback", function (done) {
|
||||
var result = client.validateOptionsAndCallback(null, function () { });
|
||||
assert.equal(null, result.options);
|
||||
assert.equal("object", typeof result.options);
|
||||
|
||||
assert.equal("function", typeof result.callback);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
it("[nativeApi] invalid string options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback("foo", function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid number options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback(0, function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "number"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid bool options", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback(false, function () { }); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "boolean"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid string callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, "bar"); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid number callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, 0); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "number"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid boolean callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback({}, false); },
|
||||
/The "callback" parameter must be of type "function". Actual type is: "boolean"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid options, invalid callback", function (done) {
|
||||
assert.throws(
|
||||
function () { client.validateOptionsAndCallback("foo", "bar"); },
|
||||
/The "options" parameter must be of type "object". Actual type is: "string"/
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sprintf Unit Tests", function () {
|
||||
var client = new DocumentDBClient(host, { masterKey: masterKey });
|
||||
|
||||
it("[nativeApi] 0 strings", function (done) {
|
||||
assert.equal("foo", client.sprintf("foo"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] 1 string", function (done) {
|
||||
assert.equal("foo", client.sprintf("%s", "foo"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] 2 strings", function (done) {
|
||||
assert.equal("foobar", client.sprintf("%s%s", "foo", "bar"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] 3 strings", function (done) {
|
||||
assert.equal("foobarbaz", client.sprintf("%s%s%s", "foo", "bar", "baz"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] %% escapes", function (done) {
|
||||
assert.equal('%s', client.sprintf("%%s", 'foo'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Range Tests", function () {
|
||||
describe("constructor", function () {
|
||||
var invalidOptionsTest = function (options, expectedError, done) {
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new Range(options);
|
||||
},
|
||||
expectedError);
|
||||
done();
|
||||
}
|
||||
|
||||
var optionsIsNullTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options' is null/, done);
|
||||
}
|
||||
|
||||
var optionsIsNotAnObjectTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options' is not an object/, done);
|
||||
}
|
||||
|
||||
var comparisonFunctionIsNotAFunctionTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options.compareFunction' is not a function/, done);
|
||||
}
|
||||
|
||||
var invalidRangeTest = function (options, done) {
|
||||
invalidOptionsTest(options, /Invalid argument: 'options.low' must be less than or equal than 'options.high'/, done);
|
||||
}
|
||||
|
||||
it("[nativeApi] options - undefined (ommited argument)", function (done) {
|
||||
assert(new Range());
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] options - undefined (literal argument)", function (done) {
|
||||
assert(new Range(undefined));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] options - null ", function (done) {
|
||||
var options = null;
|
||||
optionsIsNullTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] options - number", function (done) {
|
||||
var options = 0;
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid options - string", function (done) {
|
||||
var options = "";
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid options - boolean", function (done) {
|
||||
var options = false;
|
||||
optionsIsNotAnObjectTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid compareFunction - null", function (done) {
|
||||
var options = { compareFunction: null };
|
||||
comparisonFunctionIsNotAFunctionTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid compareFunction - string", function (done) {
|
||||
var options = { compareFunction: "" };
|
||||
comparisonFunctionIsNotAFunctionTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid compareFunction - number", function (done) {
|
||||
var options = { compareFunction: 0 };
|
||||
comparisonFunctionIsNotAFunctionTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid compareFunction - boolean", function (done) {
|
||||
var options = { compareFunction: false };
|
||||
comparisonFunctionIsNotAFunctionTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid compareFunction - object", function (done) {
|
||||
var options = { compareFunction: {} };
|
||||
comparisonFunctionIsNotAFunctionTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid range - low greater than high", function (done) {
|
||||
var options = { low: 2, high: 1 };
|
||||
invalidRangeTest(options, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] compareFunction exception is thrown - inside constructor ", function (done) {
|
||||
var options = {
|
||||
low: 0,
|
||||
high: 1,
|
||||
compareFunction: function (a, b) {
|
||||
throw new Error("Compare error");
|
||||
}
|
||||
};
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new Range(options);
|
||||
},
|
||||
/Error: Compare error/);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] compareFunction exception is thrown - outside constructor ", function (done) {
|
||||
var options = {
|
||||
low: 0,
|
||||
high: 1,
|
||||
compareFunction: function (a, b) {
|
||||
if (a === 1) {
|
||||
throw new Error("Compare error");
|
||||
}
|
||||
}
|
||||
};
|
||||
var r = new Range(options);
|
||||
assert.throws(
|
||||
function () {
|
||||
r._compare(1, 0);
|
||||
},
|
||||
/Error: Compare error/);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] Range instances are frozen", function (done) {
|
||||
var r = new Range();
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
r.compareFunction = 1;
|
||||
},
|
||||
/Cannot assign to read only property 'compareFunction' of /
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("contains", function () {
|
||||
it("[nativeApi] undefined,undefined contains undefined is true", function (done) {
|
||||
var r = new Range();
|
||||
assert(r.contains(undefined));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] undefined,undefined contains null is false", function (done) {
|
||||
var r = new Range();
|
||||
assert(!r.contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] null,null contains undefined is true", function (done) {
|
||||
var r = new Range({ low: null });
|
||||
assert(r.contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] null,null contains null is true", function (done) {
|
||||
var r = new Range({ low: null });
|
||||
assert(r.contains(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] range contains self is true - default range", function (done) {
|
||||
var r = new Range();
|
||||
assert(r.contains(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] range contains self is true - non-default range", function (done) {
|
||||
var r = new Range({ low: "A" });
|
||||
assert(r.contains(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,D contains B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "D" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,C contains A,D is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "D" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,C contains B,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
var r2 = new Range({ low: "B", high: "D" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,D contains A,C is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "C" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,B contains B,C is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,C contains A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,B contains C,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "C", high: "D" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] C,D contains A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "C", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1.contains(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,C contains B is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
assert(r1.contains("B"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,C contains A is false", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
assert(!r1.contains("A"));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,B contains C is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1.contains("C"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("intersect", function () {
|
||||
var otherIsUndefinedOrNullTest = function (other, done) {
|
||||
var r = new Range();
|
||||
assert.throws(
|
||||
function () {
|
||||
r.intersect(other);
|
||||
},
|
||||
/Invalid Argument: 'other' is undefined or null/
|
||||
);
|
||||
done();
|
||||
};
|
||||
|
||||
it("[nativeApi] error - other is undefined", function (done) {
|
||||
otherIsUndefinedOrNullTest(undefined, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] error - other is null", function (done) {
|
||||
otherIsUndefinedOrNullTest(null, done);
|
||||
});
|
||||
|
||||
it("[nativeApi] range intersect self is true - default range", function (done) {
|
||||
var r = new Range();
|
||||
assert(r.intersect(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] R intersect R is true - non default range", function (done) {
|
||||
var r = new Range({ low: 1, high: "2" });
|
||||
assert(r.intersect(r));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,D insersects B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "D" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,C insersects A,D is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "D" });
|
||||
assert(r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,C insersects B,D is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "C" });
|
||||
var r2 = new Range({ low: "B", high: "D" });
|
||||
assert(r1.intersect(r2));
|
||||
assert(r2.intersect(r1));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,D insersects A,C is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "C" });
|
||||
assert(r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,B insersects B,C is true", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "B", high: "C" });
|
||||
assert(r1.intersect(r2));
|
||||
assert(r2.intersect(r1));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] B,C insersects A,B is true", function (done) {
|
||||
var r1 = new Range({ low: "B", high: "C" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] A,B insersects C,D is false", function (done) {
|
||||
var r1 = new Range({ low: "A", high: "B" });
|
||||
var r2 = new Range({ low: "C", high: "D" });
|
||||
assert(!r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] C,D insersects A,B is false", function (done) {
|
||||
var r1 = new Range({ low: "C", high: "D" });
|
||||
var r2 = new Range({ low: "A", high: "B" });
|
||||
assert(!r1.intersect(r2));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("toString", function () {
|
||||
var toStringTest = function (options, expectedString, done) {
|
||||
var r = new Range(options);
|
||||
assert.strictEqual(r.toString(), expectedString);
|
||||
done();
|
||||
};
|
||||
|
||||
it("[nativeApi] undefined values", function (done) {
|
||||
toStringTest(undefined, "undefined,undefined", done);
|
||||
});
|
||||
it("[nativeApi] null values", function (done) {
|
||||
toStringTest({ low: null }, "null,null", done);
|
||||
});
|
||||
it("[nativeApi] NaN values", function (done) {
|
||||
toStringTest({ low: NaN }, "NaN,NaN", done);
|
||||
});
|
||||
it("[nativeApi] number values", function (done) {
|
||||
toStringTest({ low: 1 }, "1,1", done);
|
||||
});
|
||||
it("[nativeApi] string values", function (done) {
|
||||
toStringTest({ low: "a" }, "a,a", done);
|
||||
});
|
||||
it("[nativeApi] boolean values", function (done) {
|
||||
toStringTest({ low: false, high: true }, "false,true", done);
|
||||
});
|
||||
it("[nativeApi] object values", function (done) {
|
||||
toStringTest({ low: {} }, "[object Object],[object Object]", done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_compare", function () {
|
||||
var r = new Range();
|
||||
|
||||
var rangeWithComparisonAsNumbers = new Range({
|
||||
compareFunction: function (a, b) {
|
||||
return a - b;
|
||||
}
|
||||
});
|
||||
|
||||
var rangeWithConstantComparison = new Range({
|
||||
compareFunction: function (a, b) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("[nativeApi] _compare(undefined, undefined) === 0", function (done) {
|
||||
assert(r._compare() === 0);
|
||||
assert(r._compare(undefined) === 0);
|
||||
assert(r._compare(undefined, undefined) === 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _compare(undefined, y) > 0", function (done) {
|
||||
assert(r._compare(undefined, null) > 0);
|
||||
assert(r._compare(undefined, -NaN) > 0);
|
||||
assert(r._compare(undefined, 0) > 0);
|
||||
assert(r._compare(undefined, NaN) > 0);
|
||||
assert(r._compare(undefined, true) > 0);
|
||||
assert(r._compare(undefined, false) > 0);
|
||||
assert(r._compare(undefined, "a") > 0);
|
||||
assert(r._compare(undefined, "undefined") > 0);
|
||||
assert(r._compare(undefined, "z") > 0);
|
||||
assert(r._compare(undefined, []) > 0);
|
||||
assert(r._compare(undefined, {}) > 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _compare(x, undefined) < -1", function (done) {
|
||||
assert(r._compare(null) < 0);
|
||||
assert(r._compare(-NaN) < 0);
|
||||
assert(r._compare(0) < 0);
|
||||
assert(r._compare(NaN) < 0);
|
||||
assert(r._compare(true) < 0);
|
||||
assert(r._compare(false) < 0);
|
||||
assert(r._compare("a") < 0);
|
||||
assert(r._compare("undefined") < 0);
|
||||
assert(r._compare("z") < 0);
|
||||
assert(r._compare([]) < 0);
|
||||
assert(r._compare({}) < 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _compare values as strings (default)", function (done) {
|
||||
assert(r._compare("A", "B") < 0);
|
||||
assert(r._compare("", "") === 0);
|
||||
assert(r._compare("B", "A") > 0);
|
||||
assert(r._compare("10", "2") < 0);
|
||||
assert(r._compare(10, "02") > 0);
|
||||
assert(r._compare(10, 2) < 0);
|
||||
assert(r._compare(null, "nulm") < 0);
|
||||
assert(r._compare(null, "null") === 0);
|
||||
assert(r._compare(null, "nulk") > 0);
|
||||
assert(r._compare(true, "truf") < 0);
|
||||
assert(r._compare(true, "true") === 0);
|
||||
assert(r._compare(true, "trud") > 0);
|
||||
assert(r._compare({}, "[object Object]") === 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _compare values as numbers", function (done) {
|
||||
assert(rangeWithComparisonAsNumbers._compare(undefined, 2) > 0);
|
||||
assert(rangeWithComparisonAsNumbers._compare(1, 2) < 0);
|
||||
assert(rangeWithComparisonAsNumbers._compare(0, 0) === 0);
|
||||
assert(rangeWithComparisonAsNumbers._compare(10, 2) > 0);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _compare always return 0", function (done) {
|
||||
assert(rangeWithConstantComparison._compare(1, 2) === 0);
|
||||
assert(rangeWithConstantComparison._compare(2, 1) === 0);
|
||||
assert(rangeWithConstantComparison._compare(undefined, 2) > 0);
|
||||
assert(rangeWithConstantComparison._compare(1, undefined) < 0);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_isRange", function () {
|
||||
it("[nativeApi] _isRange(undefined) is false", function (done) {
|
||||
assert(!Range._isRange());
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _isRange(null) is false", function (done) {
|
||||
assert(!Range._isRange(null));
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _isRange(non-object) is false", function (done) {
|
||||
var points = [
|
||||
undefined,
|
||||
null,
|
||||
1,
|
||||
"",
|
||||
true,
|
||||
NaN,
|
||||
function () {
|
||||
},
|
||||
{},
|
||||
{
|
||||
low: ""
|
||||
}
|
||||
];
|
||||
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
assert(!Range._isRange(points[i]));
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _isRange(point) is false", function (done) {
|
||||
var ranges = [
|
||||
{
|
||||
low: "",
|
||||
high: 1
|
||||
},
|
||||
new Range()
|
||||
];
|
||||
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
assert(Range._isRange(ranges[i]));
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("RangePartitionResolver Tests", function () {
|
||||
describe("constructor", function () {
|
||||
it("[nativeApi] missing partitionKeyExtractor throws", function (done) {
|
||||
var expetcedError = /Error: partitionKeyExtractor cannot be null or undefined/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver();
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(undefined);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(null);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid partitionKeyExtractor throws", function (done) {
|
||||
var expetcedError = /partitionKeyExtractor must be either a 'string' or a 'function'/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(0);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = RangePartitionResolver(true);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(NaN);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver([]);
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver({});
|
||||
},
|
||||
expetcedError
|
||||
);
|
||||
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] missing partitionKeyMap throws", function (done) {
|
||||
var expectedError = /Error: partitionKeyMap cannot be null or undefined/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("");
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver(function () {
|
||||
});
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", null);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] invalid partitionKeyMap throws", function (done) {
|
||||
var expectedError = /Error: partitionKeyMap has to be an Array/;
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", 0);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", "");
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", true);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", NaN);
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var r = new RangePartitionResolver("", {});
|
||||
},
|
||||
expectedError
|
||||
);
|
||||
|
||||
var r = new RangePartitionResolver("", new Array());
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] valid RangePartitionResolver", function (done) {
|
||||
var resolver = new RangePartitionResolver("", []);
|
||||
assert(resolver);
|
||||
assert.strictEqual(resolver.partitionKeyExtractor, "");
|
||||
assert.deepEqual(resolver.partitionKeyMap, []);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("_getFirstContainingMapEntryOrNull", function () {
|
||||
it("[nativeApi] _getFirstContainingMapEntryOrNull - empty map returns null", function (done) {
|
||||
var ranges = [undefined, null, 0, "", true, [], {}, NaN, new Range()];
|
||||
var resolver = new RangePartitionResolver("", []);
|
||||
ranges.forEach(function (r) {
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(r);
|
||||
assert.equal(result, null);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _tryGetContainingRange - map with no containing entry returns null", function (done) {
|
||||
var mapEntry = { range: new Range({ low: "A" }), link: "link1" };
|
||||
var resolver = new RangePartitionResolver("key", [mapEntry]);
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(new Range({ low: "B" }));
|
||||
assert.equal(result, null);
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _tryGetContainingRange - map with single containing entry returns entry", function (done) {
|
||||
var mapEntry = { range: new Range(), link: "link1" };
|
||||
var resolver = new RangePartitionResolver("key", [mapEntry]);
|
||||
var result = resolver._getFirstContainingMapEntryOrNull(new Range());
|
||||
assert.deepEqual(result, { range: new Range(), link: "link1" });
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _tryGetContainingRange - map with more multiple containing entries returns first entry", function (done) {
|
||||
var map1 = [
|
||||
{ range: new Range({ low: "A", high: "B" }), link: "link1" },
|
||||
{ range: new Range({ low: "A" }), link: "link2" }
|
||||
];
|
||||
|
||||
var resolver1 = new RangePartitionResolver("key", map1);
|
||||
var result1 = resolver1._getFirstContainingMapEntryOrNull(new Range({ low: "A" }));
|
||||
assert.strictEqual(result1.link, "link1");
|
||||
|
||||
var map2 = [
|
||||
{ range: new Range({ low: "A" }), link: "link2" },
|
||||
{ range: new Range({ low: "A", high: "Z" }), link: "link1" }
|
||||
];
|
||||
|
||||
var resolver2 = new RangePartitionResolver("key", map2);
|
||||
var result2 = resolver2._getFirstContainingMapEntryOrNull(new Range({ low: "A" }));
|
||||
assert.strictEqual(result2.link, "link2");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveForCreate", function () {
|
||||
it("[nativeApi] _tryGetContainingRange - map containing parition key returns corresponding link", function (done) {
|
||||
var resolver = new RangePartitionResolver("key", [
|
||||
{ range: new Range({ low: "A", high: "M" }), link: "link1" },
|
||||
{ range: new Range({ low: "N", high: "Z" }), link: "link2" }
|
||||
]);
|
||||
var result = resolver.resolveForCreate("X");
|
||||
assert.strictEqual(result, "link2");
|
||||
done();
|
||||
});
|
||||
|
||||
it("[nativeApi] _tryGetContainingRange - map not containing parition key throws", function (done) {
|
||||
var resolver = new RangePartitionResolver("key", [
|
||||
{ range: new Range({ low: "A", high: "M" }), link: "link1" }
|
||||
]);
|
||||
|
||||
assert.throws(
|
||||
function () {
|
||||
var result = resolver.resolveForCreate("X");
|
||||
},
|
||||
/Error: Invalid operation: A containing range for 'X,X' doesn't exist in the partition map./
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("HashPartitionResolver Tests", function () {
|
||||
describe("HashPartitionResolver", function () {
|
||||
|
||||
var test = function (useUpsert, done) {
|
||||
var client = new DocumentDBClient(host, { masterKey: masterKey });
|
||||
|
@ -3273,7 +2331,7 @@ describe("NodeJS CRUD Tests", function() {
|
|||
});
|
||||
};
|
||||
|
||||
it("[promiseApi] Should do document CRUD operations with a partition resolver successfully", function (done) { test(false, done) });
|
||||
it("[promiseApi] Should do document CRUD operations with a partition resolver successfully with upsert", function (done) { test(true, done) });
|
||||
it("CRUD operations", function (done) { test(false, done) });
|
||||
it("CRUD operations with upsert", function (done) { test(true, done) });
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче