Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boris Kocherov
jio
Commits
f2943ed8
Commit
f2943ed8
authored
Dec 31, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
replicaterevisionstorage upgraded + tests
parent
5a50c92f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1173 additions
and
858 deletions
+1173
-858
src/jio.storage/replicaterevisionstorage.js
src/jio.storage/replicaterevisionstorage.js
+29
-29
test/jio.storage/replicaterevisionstorage.tests.js
test/jio.storage/replicaterevisionstorage.tests.js
+1144
-829
No files found.
src/jio.storage/replicaterevisionstorage.js
View file @
f2943ed8
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
module
(
jIO
);
module
(
jIO
);
}([
'
jio
'
],
function
(
jIO
)
{
}([
'
jio
'
],
function
(
jIO
)
{
"
use strict
"
;
"
use strict
"
;
jIO
.
addStorage
Type
(
'
replicaterevision
'
,
function
(
spec
)
{
jIO
.
addStorage
(
'
replicaterevision
'
,
function
(
spec
)
{
var
that
=
this
,
priv
=
{};
var
that
=
this
,
priv
=
{};
spec
=
spec
||
{};
spec
=
spec
||
{};
...
@@ -217,16 +217,9 @@
...
@@ -217,16 +217,9 @@
command
.
success
();
command
.
success
();
}
}
if
(
!
param
.
_id
)
{
if
(
!
param
.
_id
)
{
return
callback
({
return
callback
({
"
status
"
:
501
});
"
status
"
:
501
});
}
}
priv
.
check
(
priv
.
check
(
command
,
param
,
option
,
callback
);
command
,
param
,
option
,
callback
);
};
};
/**
/**
...
@@ -264,6 +257,16 @@
...
@@ -264,6 +257,16 @@
callback
=
callback
||
priv
.
emptyFunction
;
callback
=
callback
||
priv
.
emptyFunction
;
option
=
option
||
{};
option
=
option
||
{};
functions
.
begin
=
function
()
{
functions
.
begin
=
function
()
{
// // XXX make revision storage check and repair
// // to enable check/repair sub storage from this storage
// // by calling this function just below
// //functions.repairAllSubStorages();
// // else we assume that sub storages are good
// functions.getAllDocuments(functions.newParam(
// doc,
// option,
// repair
// ));
// };
// };
// functions.repairAllSubStorages = function () {
// functions.repairAllSubStorages = function () {
var
i
;
var
i
;
...
@@ -315,8 +318,8 @@
...
@@ -315,8 +318,8 @@
// 1: [responseB, [2]]
// 1: [responseB, [2]]
],
],
"
attachments
"
:
{
"
attachments
"
:
{
// attachmentA : {_id: attachmentA, _revs_info, _
mime
type: ..}
// attachmentA : {_id: attachmentA, _revs_info, _
content_
type: ..}
// attachmentB : {_id: attachmentB, _revs_info, _
mime
type: ..}
// attachmentB : {_id: attachmentB, _revs_info, _
content_
type: ..}
}
}
},
},
"
conflicts
"
:
{
"
conflicts
"
:
{
...
@@ -333,9 +336,9 @@
...
@@ -333,9 +336,9 @@
var
i
,
metadata
,
cloned_option
;
var
i
,
metadata
,
cloned_option
;
metadata
=
priv
.
clone
(
param
.
doc
);
metadata
=
priv
.
clone
(
param
.
doc
);
cloned_option
=
priv
.
clone
(
param
.
option
);
cloned_option
=
priv
.
clone
(
param
.
option
);
option
.
conflicts
=
true
;
cloned_
option
.
conflicts
=
true
;
option
.
revs
=
true
;
cloned_
option
.
revs
=
true
;
option
.
revs_info
=
true
;
cloned_
option
.
revs_info
=
true
;
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
// if the document is not loaded
// if the document is not loaded
priv
.
send
(
command
,
"
get
"
,
i
,
priv
.
send
(
command
,
"
get
"
,
i
,
...
@@ -356,7 +359,7 @@
...
@@ -356,7 +359,7 @@
// get document failed, exit
// get document failed, exit
param
.
deal_result_state
=
"
error
"
;
param
.
deal_result_state
=
"
error
"
;
callback
({
callback
({
"
status
"
:
"
conflict
"
,
"
status
"
:
409
,
"
message
"
:
"
An error occured on the sub storage
"
,
"
message
"
:
"
An error occured on the sub storage
"
,
"
reason
"
:
err
.
reason
"
reason
"
:
err
.
reason
},
undefined
);
},
undefined
);
...
@@ -378,6 +381,7 @@
...
@@ -378,6 +381,7 @@
// this is now the last response
// this is now the last response
functions
.
makeResponsesStats
(
param
.
responses
);
functions
.
makeResponsesStats
(
param
.
responses
);
//console.log(JSON.parse(JSON.stringify(param.responses)));
if
(
param
.
responses
.
stats_items
.
length
===
1
)
{
if
(
param
.
responses
.
stats_items
.
length
===
1
)
{
// the responses are equals!
// the responses are equals!
response_object
.
ok
=
true
;
response_object
.
ok
=
true
;
...
@@ -394,7 +398,7 @@
...
@@ -394,7 +398,7 @@
if
(
param
.
repair
===
false
)
{
if
(
param
.
repair
===
false
)
{
// do not repair
// do not repair
callback
({
callback
({
"
status
"
:
"
conflict
"
,
"
status
"
:
409
,
"
message
"
:
"
Some documents are different in the sub storages
"
,
"
message
"
:
"
Some documents are different in the sub storages
"
,
"
reason
"
:
"
Storage contents differ
"
"
reason
"
:
"
Storage contents differ
"
},
undefined
);
},
undefined
);
...
@@ -460,7 +464,7 @@
...
@@ -460,7 +464,7 @@
/*jslint unparam: true */
/*jslint unparam: true */
if
(
err
)
{
if
(
err
)
{
callback
({
callback
({
"
status
"
:
"
conflict
"
,
"
status
"
:
409
,
"
message
"
:
"
Unable to retreive attachments
"
,
"
message
"
:
"
Unable to retreive attachments
"
,
"
reason
"
:
err
.
reason
"
reason
"
:
err
.
reason
},
undefined
);
},
undefined
);
...
@@ -513,7 +517,7 @@
...
@@ -513,7 +517,7 @@
if
(
new_doc
.
_attachments
.
hasOwnProperty
(
i
))
{
if
(
new_doc
.
_attachments
.
hasOwnProperty
(
i
))
{
attachment_to_put
.
push
({
attachment_to_put
.
push
({
"
_id
"
:
i
,
"
_id
"
:
i
,
"
_
mime
type
"
:
new_doc
.
_attachments
[
i
].
content_type
,
"
_
content_
type
"
:
new_doc
.
_attachments
[
i
].
content_type
,
"
_revs_info
"
:
new_doc
.
_revs_info
"
_revs_info
"
:
new_doc
.
_revs_info
});
});
}
}
...
@@ -555,9 +559,7 @@
...
@@ -555,9 +559,7 @@
var
i
,
attachment
;
var
i
,
attachment
;
if
(
err
)
{
if
(
err
)
{
return
callback
({
return
callback
({
"
status
"
:
40
,
"
status
"
:
409
,
"
statusText
"
:
"
Check Failed
"
,
"
error
"
:
"
check_failed
"
,
"
message
"
:
"
Unable to copy attachments
"
,
"
message
"
:
"
Unable to copy attachments
"
,
"
reason
"
:
err
.
reason
"
reason
"
:
err
.
reason
},
undefined
);
},
undefined
);
...
@@ -566,7 +568,7 @@
...
@@ -566,7 +568,7 @@
attachment
=
{
attachment
=
{
"
_id
"
:
param
.
doc
.
_id
,
"
_id
"
:
param
.
doc
.
_id
,
"
_attachment
"
:
attachment_to_put
[
i
].
_id
,
"
_attachment
"
:
attachment_to_put
[
i
].
_id
,
"
_
mimetype
"
:
attachment_to_put
[
i
].
_mime
type
,
"
_
content_type
"
:
attachment_to_put
[
i
].
_content_
type
,
"
_revs_info
"
:
attachment_to_put
[
i
].
_revs_info
,
"
_revs_info
"
:
attachment_to_put
[
i
].
_revs_info
,
// "_revs_info": param.responses.list[index]._revs_info,
// "_revs_info": param.responses.list[index]._revs_info,
"
_data
"
:
param
.
responses
.
attachments
[
attachment_to_put
[
i
].
_id
]
"
_data
"
:
param
.
responses
.
attachments
[
attachment_to_put
[
i
].
_id
]
...
@@ -640,7 +642,7 @@
...
@@ -640,7 +642,7 @@
* @param {object} command The JIO command
* @param {object} command The JIO command
*/
*/
that
.
post
=
function
(
command
,
metadata
,
option
)
{
that
.
post
=
function
(
command
,
metadata
,
option
)
{
that
.
genericRequest
(
command
,
"
p
u
t
"
,
metadata
,
option
);
that
.
genericRequest
(
command
,
"
p
os
t
"
,
metadata
,
option
);
};
};
/**
/**
...
@@ -649,7 +651,7 @@
...
@@ -649,7 +651,7 @@
* @param {object} command The JIO command
* @param {object} command The JIO command
*/
*/
that
.
put
=
function
(
command
,
metadata
,
option
)
{
that
.
put
=
function
(
command
,
metadata
,
option
)
{
that
.
genericRequest
(
command
,
"
p
os
t
"
,
metadata
,
option
);
that
.
genericRequest
(
command
,
"
p
u
t
"
,
metadata
,
option
);
};
};
/**
/**
...
@@ -696,7 +698,5 @@
...
@@ -696,7 +698,5 @@
that
.
removeAttachment
=
function
(
command
,
param
,
option
)
{
that
.
removeAttachment
=
function
(
command
,
param
,
option
)
{
that
.
genericRequest
(
command
,
"
removeAttachment
"
,
param
,
option
);
that
.
genericRequest
(
command
,
"
removeAttachment
"
,
param
,
option
);
};
};
return
that
;
});
});
}));
}));
test/jio.storage/replicaterevisionstorage.tests.js
View file @
f2943ed8
/*jslint indent: 2, maxlen: 80, nomen: true */
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO,
jio_tests
, hex_sha256, test, ok, deepEqual, sinon,
/*global define, jIO,
test_util
, hex_sha256, test, ok, deepEqual, sinon,
expect, module */
expect, module
, stop, start, RSVP
*/
// define([module_name], [dependencies], module);
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
(
function
(
dependencies
,
module
)
{
...
@@ -8,242 +8,288 @@
...
@@ -8,242 +8,288 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
return
define
(
dependencies
,
module
);
}
}
module
(
jIO
,
jio_tests
,
{
hex_sha256
:
hex_sha256
}
);
module
(
jIO
,
test_util
,
{
hex_sha256
:
hex_sha256
},
RSVP
);
}([
}([
'
jio
'
,
'
jio
'
,
'
jio_tests
'
,
'
test_util
'
,
'
sha256
'
,
'
sha256
'
,
'
rsvp
'
,
'
localstorage
'
,
'
localstorage
'
,
'
revisionstorage
'
,
'
revisionstorage
'
,
'
replicaterevisionstorage
'
'
replicaterevisionstorage
'
],
function
(
jIO
,
util
,
sha256
)
{
],
function
(
jIO
,
util
,
sha256
,
RSVP
)
{
"
use strict
"
;
"
use strict
"
;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Tools
// Tools
/**
var
tool
=
{
* Clones all native object in deep. Managed types: Object, Array, String,
"
deepClone
"
:
jIO
.
util
.
deepClone
,
* Number, Boolean, Function, null.
"
uniqueJSONStringify
"
:
jIO
.
util
.
uniqueJSONStringify
,
*
"
readBlobAsBinaryString
"
:
jIO
.
util
.
readBlobAsBinaryString
* @param {A} object The object to clone
* @return {A} The cloned object
*/
function
deepClone
(
object
)
{
var
i
,
cloned
;
if
(
Array
.
isArray
(
object
))
{
cloned
=
[];
for
(
i
=
0
;
i
<
object
.
length
;
i
+=
1
)
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
return
cloned
;
}
if
(
typeof
object
===
"
object
"
)
{
cloned
=
{};
for
(
i
in
object
)
{
if
(
object
.
hasOwnProperty
(
i
))
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
}
return
cloned
;
}
return
object
;
}
function
generateTools
()
{
return
{
clock
:
sinon
.
useFakeTimers
(),
spy
:
util
.
ospy
,
tick
:
util
.
otick
};
};
function
reverse
(
promise
)
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
promise
.
then
(
reject
,
resolve
,
notify
);
},
function
()
{
promise
.
cancel
();
});
}
}
function
generateRevisionHash
(
doc
,
revisions
,
deleted_flag
)
{
function
generateRevisionHash
(
doc
,
revisions
,
deleted_flag
)
{
var
string
;
var
string
;
doc
=
deepClone
(
doc
);
doc
=
tool
.
deepClone
(
doc
);
delete
doc
.
_rev
;
delete
doc
.
_rev
;
delete
doc
.
_revs
;
delete
doc
.
_revs
;
delete
doc
.
_revs_info
;
delete
doc
.
_revs_info
;
string
=
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revisions
)
+
string
=
tool
.
uniqueJSONStringify
(
doc
)
+
tool
.
uniqueJSONStringify
(
revisions
)
+
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
return
sha256
.
hex_sha256
(
string
);
return
sha256
.
hex_sha256
(
string
);
}
}
function
unexpectedError
(
error
)
{
if
(
error
instanceof
Error
)
{
deepEqual
([
error
.
name
+
"
:
"
+
error
.
message
,
error
],
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
}
else
{
deepEqual
(
error
,
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Tests
// Tests
module
(
"
Replicate Revision Storage
"
);
module
(
"
Replicate Revision Storage
"
);
var
testReplicateRevisionStorage
=
function
(
sinon
,
jio_description
)
{
function
testReplicateRevisionStorage
(
jio_description
)
{
/*jslint unparam: true */
var
o
=
generateTools
(),
leavesAction
,
generateLocalPath
;
var
shared
=
{},
jio
,
jio_leaves
=
[];
shared
.
workspace
=
{};
jio
=
jIO
.
createJIO
(
jio_description
,
{
"
workspace
"
:
shared
.
workspace
});
o
.
jio
=
jIO
.
newJio
(
jio_description
);
function
leavesAction
(
action
,
storage_description
)
{
generateLocalPath
=
function
(
storage_description
)
{
return
"
jio/localstorage/
"
+
storage_description
.
username
+
"
/
"
+
storage_description
.
application_name
;
};
leavesAction
=
function
(
action
,
storage_description
,
param
)
{
var
i
;
var
i
;
if
(
param
===
undefined
)
{
if
(
storage_description
.
type
===
"
replicaterevision
"
)
{
param
=
{};
}
else
{
param
=
deepClone
(
param
);
}
if
(
storage_description
.
storage_list
!==
undefined
)
{
// it is the replicate revision storage tree
// it is the replicate revision storage tree
for
(
i
=
0
;
i
<
storage_description
.
storage_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
storage_description
.
storage_list
.
length
;
i
+=
1
)
{
leavesAction
(
action
,
storage_description
.
storage_list
[
i
]
,
param
);
leavesAction
(
action
,
storage_description
.
storage_list
[
i
]);
}
}
}
else
if
(
storage_description
.
sub_storage
!==
undefined
)
{
}
else
if
(
storage_description
.
type
===
"
revision
"
)
{
// it is the revision storage tree
// it is the revision storage tree
param
.
revision
=
true
;
leavesAction
(
action
,
storage_description
.
sub_storage
);
leavesAction
(
action
,
storage_description
.
sub_storage
,
param
);
}
else
{
}
else
{
// it is the storage tree leaf
// it is the storage tree leaf
param
[
storage_description
.
type
]
=
true
;
action
(
storage_description
);
action
(
storage_description
,
param
);
}
}
leavesAction
(
function
(
storage_description
)
{
jio_leaves
.
push
(
jIO
.
createJIO
(
storage_description
,
{
"
workspace
"
:
shared
.
workspace
}));
},
jio_description
);
jio_leaves
.
run
=
function
(
method
,
argument
)
{
var
i
,
promises
=
[];
for
(
i
=
0
;
i
<
this
.
length
;
i
+=
1
)
{
promises
[
i
]
=
this
[
i
][
method
].
apply
(
this
[
i
],
argument
);
}
}
return
RSVP
.
all
(
promises
);
};
};
o
.
leavesAction
=
function
(
action
)
{
jio_leaves
.
get
=
function
()
{
leavesAction
(
action
,
jio_description
);
return
this
.
run
(
"
get
"
,
arguments
);
};
jio_leaves
.
allDocs
=
function
()
{
return
this
.
run
(
"
allDocs
"
,
arguments
);
};
};
// post a new document without id
stop
();
o
.
doc
=
{
"
title
"
:
"
post document without id
"
};
o
.
spy
(
o
,
"
status
"
,
undefined
,
"
Post document (without id)
"
);
o
.
jio
.
post
(
o
.
doc
,
function
(
err
,
response
)
{
o
.
f
.
apply
(
arguments
);
o
.
response_rev
=
(
err
||
response
).
rev
;
if
(
util
.
isUuid
((
err
||
response
).
id
))
{
ok
(
true
,
"
Uuid format
"
);
o
.
uuid
=
(
err
||
response
).
id
;
}
else
{
deepEqual
((
err
||
response
).
id
,
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
"
,
"
Uuid format
"
);
}
});
o
.
tick
(
o
);
// check document
// post a new document without id
o
.
doc
.
_id
=
o
.
uuid
;
shared
.
doc
=
{
"
title
"
:
"
post document without id
"
};
o
.
revisions
=
{
"
start
"
:
0
,
"
ids
"
:
[]};
o
.
rev_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
revisions
);
jio
.
post
(
shared
.
doc
).
then
(
function
(
answer
)
{
o
.
rev
=
"
1-
"
+
o
.
rev_hash
;
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
shared
.
revisions
=
{
"
start
"
:
0
,
"
ids
"
:
[]};
var
suffix
=
""
,
doc
=
deepClone
(
o
.
doc
);
shared
.
uuid
=
answer
.
id
;
if
(
param
.
revision
)
{
shared
.
rev
=
answer
.
rev
;
deepEqual
(
o
.
response_rev
,
o
.
rev
,
"
Check revision
"
);
shared
.
rev_hash
=
shared
.
rev
.
slice
(
2
);
doc
.
_id
+=
"
.
"
+
o
.
rev
;
shared
.
doc
.
_id
=
shared
.
uuid
;
suffix
=
"
.
"
+
o
.
rev
;
ok
(
util
.
isUuid
(
shared
.
uuid
),
"
Uuid should look like
"
+
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx :
"
+
shared
.
uuid
);
deepEqual
(
answer
,
{
"
id
"
:
shared
.
uuid
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
"
1-
"
+
generateRevisionHash
(
shared
.
doc
,
shared
.
revisions
),
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post document (without id)
"
);
delete
shared
.
doc
.
_id
;
return
jio_leaves
.
get
({
"
_id
"
:
shared
.
uuid
+
"
.
"
+
shared
.
rev
});
}).
then
(
function
(
answers
)
{
var
i
;
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
deepEqual
(
answers
[
i
].
data
,
{
"
_id
"
:
shared
.
uuid
+
"
.
"
+
shared
.
rev
,
"
title
"
:
"
post document without id
"
},
"
Check document
"
+
(
i
+
1
));
}
}
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/
"
+
o
.
uuid
+
suffix
),
doc
,
"
Check document
"
);
});
// get the post document without revision
return
jio
.
get
({
"
_id
"
:
shared
.
uuid
},
{
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
o
.
uuid
,
"
title
"
:
"
post document without id
"
,
"
_rev
"
:
o
.
rev
,
"
_revisions
"
:
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev_hash
]},
"
_revs_info
"
:
[{
"
rev
"
:
o
.
rev
,
"
status
"
:
"
available
"
}]
},
"
Get the generated document, the winner
"
);
o
.
jio
.
get
({
"
_id
"
:
o
.
uuid
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
{
"
_id
"
:
shared
.
uuid
,
"
_rev
"
:
shared
.
rev
,
"
_revisions
"
:
{
"
ids
"
:
[
shared
.
rev_hash
],
"
start
"
:
1
},
"
_revs_info
"
:
[{
"
rev
"
:
shared
.
rev
,
"
status
"
:
"
available
"
}],
"
title
"
:
"
post document without id
"
},
"
Get the generated document, the winner
"
);
// post a new document with id
// post a new document with id
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post new doc with id
"
};
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post new doc with id
"
};
o
.
rev1_1_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
revisions
);
shared
.
rev1_1_hash
=
generateRevisionHash
(
shared
.
doc
,
shared
.
revisions
);
o
.
rev1_1
=
"
1-
"
+
o
.
rev1_1_hash
;
shared
.
rev1_1
=
"
1-
"
+
shared
.
rev1_1_hash
;
o
.
rev1_1_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev1_1_hash
]};
shared
.
rev1_1_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
shared
.
rev1_1_hash
]};
o
.
rev1_1_revs_info
=
[{
"
rev
"
:
o
.
rev1_1
,
"
status
"
:
"
available
"
}];
shared
.
rev1_1_revs_info
=
[{
"
rev
"
:
shared
.
rev1_1
,
"
status
"
:
"
available
"
}];
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev1_1
},
"
Post new document with an id
"
);
return
jio
.
post
(
shared
.
doc
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev1_1
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post new document with an id
"
);
// /
// /
// |
// |
// 1-1
// 1-1
// check document
// check document
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.
"
+
shared
.
rev1_1
});
var
suffix
=
""
,
doc
=
deepClone
(
o
.
doc
);
if
(
param
.
revision
)
{
}).
then
(
function
(
answers
)
{
doc
.
_id
+=
"
.
"
+
o
.
rev1_1
;
var
i
;
suffix
=
"
.
"
+
o
.
rev1_1
;
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
deepEqual
(
answers
[
i
].
data
,
{
"
_id
"
:
"
doc1.
"
+
shared
.
rev1_1
,
"
title
"
:
"
post new doc with id
"
},
"
Check document
"
+
(
i
+
1
));
}
}
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/doc1
"
+
suffix
),
doc
,
"
Check document
"
);
});
// get the post document without revision
// get the post document without revision
o
.
spy
(
o
,
"
value
"
,
{
return
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post new doc with id
"
,
"
_rev
"
:
o
.
rev1_1
,
"
_revisions
"
:
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev1_1_hash
]},
"
_revs_info
"
:
[{
"
rev
"
:
o
.
rev1_1
,
"
status
"
:
"
available
"
}]
},
"
Get the previous document (without revision)
"
);
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
{
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev1_1
,
"
_revisions
"
:
{
"
start
"
:
1
,
"
ids
"
:
[
shared
.
rev1_1_hash
]},
"
_revs_info
"
:
[{
"
rev
"
:
shared
.
rev1_1
,
"
status
"
:
"
available
"
}],
"
title
"
:
"
post new doc with id
"
},
"
Get the previous document (without revision)
"
);
// post same document without revision
// post same document without revision
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post same document without revision
"
};
shared
.
doc
=
{
o
.
rev1_2_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
revisions
);
"
_id
"
:
"
doc1
"
,
o
.
rev1_2
=
"
1-
"
+
o
.
rev1_2_hash
;
"
title
"
:
"
post same document without revision
"
o
.
rev1_2_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev1_2_hash
]};
};
o
.
rev1_2_revs_info
=
[{
"
rev
"
:
o
.
rev1_2
,
"
status
"
:
"
available
"
}];
shared
.
rev1_2_hash
=
generateRevisionHash
(
shared
.
doc
,
shared
.
revisions
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev1_2
},
shared
.
rev1_2
=
"
1-
"
+
shared
.
rev1_2_hash
;
"
Post same document (without revision)
"
);
shared
.
rev1_2_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
shared
.
rev1_2_hash
]};
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
shared
.
rev1_2_revs_info
=
[{
"
rev
"
:
shared
.
rev1_2
,
"
status
"
:
"
available
"
}];
o
.
tick
(
o
);
return
jio
.
post
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev1_2
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post same document (without revision)
"
);
// /
// /
// / \
// / \
// 1-1 1-2
// 1-1 1-2
// check document
// check document
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.
"
+
shared
.
rev1_2
});
var
suffix
=
""
,
doc
=
deepClone
(
o
.
doc
);
if
(
param
.
revision
)
{
}).
then
(
function
(
answers
)
{
doc
.
_id
+=
"
.
"
+
o
.
rev1_2
;
var
i
;
suffix
=
"
.
"
+
o
.
rev1_2
;
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
deepEqual
(
answers
[
i
].
data
,
{
"
_id
"
:
"
doc1.
"
+
shared
.
rev1_2
,
"
title
"
:
"
post same document without revision
"
},
"
Check document
"
+
(
i
+
1
));
}
}
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/doc1
"
+
suffix
),
doc
,
"
Check document
"
);
});
// post a new revision
// post a new revision
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post new revision
"
,
"
_rev
"
:
o
.
rev1_2
};
shared
.
doc
=
{
o
.
revisions
.
start
+=
1
;
"
_id
"
:
"
doc1
"
,
o
.
revisions
.
ids
.
unshift
(
o
.
rev1_2_hash
);
"
title
"
:
"
post new revision
"
,
o
.
rev2_3_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
revisions
);
"
_rev
"
:
shared
.
rev1_2
o
.
rev2_3
=
"
2-
"
+
o
.
rev2_3_hash
;
};
o
.
rev2_3_history
=
deepClone
(
o
.
rev1_2_history
);
shared
.
revisions
.
start
+=
1
;
o
.
rev2_3_history
.
start
+=
1
;
shared
.
revisions
.
ids
.
unshift
(
shared
.
rev1_2_hash
);
o
.
rev2_3_history
.
ids
.
unshift
(
o
.
rev2_3_hash
);
shared
.
rev2_3_hash
=
generateRevisionHash
(
shared
.
doc
,
shared
.
revisions
);
o
.
rev2_3_revs_info
=
deepClone
(
o
.
rev1_2_revs_info
);
shared
.
rev2_3
=
"
2-
"
+
shared
.
rev2_3_hash
;
o
.
rev2_3_revs_info
.
unshift
({
"
rev
"
:
o
.
rev2_3
,
"
status
"
:
"
available
"
});
shared
.
rev2_3_history
=
tool
.
deepClone
(
shared
.
rev1_2_history
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev2_3
},
shared
.
rev2_3_history
.
start
+=
1
;
"
Post document (with revision)
"
);
shared
.
rev2_3_history
.
ids
.
unshift
(
shared
.
rev2_3_hash
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
shared
.
rev2_3_revs_info
=
tool
.
deepClone
(
shared
.
rev1_2_revs_info
);
o
.
tick
(
o
);
shared
.
rev2_3_revs_info
.
unshift
({
"
rev
"
:
shared
.
rev2_3
,
"
status
"
:
"
available
"
});
return
jio
.
post
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev2_3
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post document (with revision)
"
);
// /
// /
// / \
// / \
...
@@ -252,49 +298,57 @@
...
@@ -252,49 +298,57 @@
// 2-3
// 2-3
// check document
// check document
o
.
leavesAction
(
function
(
storage_description
,
param
)
{
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.
"
+
shared
.
rev2_3
});
var
suffix
=
""
,
doc
=
deepClone
(
o
.
doc
);
delete
doc
.
_rev
;
}).
then
(
function
(
answers
)
{
if
(
param
.
revision
)
{
var
i
;
doc
.
_id
+=
"
.
"
+
o
.
rev2_3
;
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
suffix
=
"
.
"
+
o
.
rev2_3
;
deepEqual
(
answers
[
i
].
data
,
{
"
_id
"
:
"
doc1.
"
+
shared
.
rev2_3
,
"
title
"
:
"
post new revision
"
},
"
Check document
"
+
(
i
+
1
));
}
}
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
generateLocalPath
(
storage_description
)
+
"
/doc1
"
+
suffix
),
doc
,
"
Check document
"
);
});
// get the post document with revision
// get the post document with revision
o
.
spy
(
o
,
"
value
"
,
{
return
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev1_2
},
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
post same document without revision
"
,
"
_rev
"
:
o
.
rev1_2
,
"
_revisions
"
:
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev1_2_hash
]},
"
_revs_info
"
:
[{
"
rev
"
:
o
.
rev1_2
,
"
status
"
:
"
available
"
}],
"
_conflicts
"
:
[
o
.
rev1_1
]
},
"
Get the previous document (with revision)
"
);
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev1_2
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
// put document without id
}).
then
(
function
(
answer
)
{
o
.
spy
(
o
,
"
status
"
,
20
,
"
Put document without id
"
);
o
.
jio
.
put
({},
o
.
f
);
deepEqual
(
answer
.
data
,
{
o
.
tick
(
o
);
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev1_2
,
"
_revisions
"
:
{
"
start
"
:
1
,
"
ids
"
:
[
shared
.
rev1_2_hash
]},
"
_revs_info
"
:
[{
"
rev
"
:
shared
.
rev1_2
,
"
status
"
:
"
available
"
}],
"
_conflicts
"
:
[
shared
.
rev1_1
],
"
title
"
:
"
post same document without revision
"
},
"
Get the previous document (with revision)
"
);
// put document without rev
// put document without rev
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
put new document
"
};
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
put new document
"
};
o
.
rev1_4_hash
=
generateRevisionHash
(
o
.
doc
,
{
"
start
"
:
0
,
"
ids
"
:
[]});
shared
.
rev1_4_hash
=
generateRevisionHash
(
shared
.
doc
,
{
o
.
rev1_4
=
"
1-
"
+
o
.
rev1_4_hash
;
"
start
"
:
0
,
o
.
rev1_4_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
o
.
rev1_4_hash
]};
"
ids
"
:
[]
o
.
rev1_4_revs_info
=
[{
"
rev
"
:
o
.
rev1_4
,
"
status
"
:
"
available
"
}];
});
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
doc1
"
,
"
ok
"
:
true
,
"
rev
"
:
o
.
rev1_4
},
shared
.
rev1_4
=
"
1-
"
+
shared
.
rev1_4_hash
;
"
Put document without rev
"
);
shared
.
rev1_4_history
=
{
"
start
"
:
1
,
"
ids
"
:
[
shared
.
rev1_4_hash
]};
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
shared
.
rev1_4_revs_info
=
[{
"
rev
"
:
shared
.
rev1_4
,
"
status
"
:
"
available
"
}];
o
.
tick
(
o
);
return
jio
.
put
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
put
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev1_4
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Put document without rev
"
);
// __/__
// __/__
// / | \
// / | \
...
@@ -303,16 +357,36 @@
...
@@ -303,16 +357,36 @@
// 2-3
// 2-3
// put new revision
// put new revision
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
title
"
:
"
put new revision
"
,
"
_rev
"
:
o
.
rev1_4
};
shared
.
doc
=
{
o
.
rev2_5_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev1_4_history
);
"
_id
"
:
"
doc1
"
,
o
.
rev2_5
=
"
2-
"
+
o
.
rev2_5_hash
;
"
title
"
:
"
put new revision
"
,
o
.
rev2_5_history
=
{
"
start
"
:
2
,
"
ids
"
:
[
o
.
rev2_5_hash
,
o
.
rev1_4_hash
]};
"
_rev
"
:
shared
.
rev1_4
o
.
rev2_5_revs_info
=
deepClone
(
o
.
rev1_4_revs_info
);
};
o
.
rev2_5_revs_info
.
unshift
({
"
rev
"
:
o
.
rev2_5
,
"
status
"
:
"
available
"
});
shared
.
rev2_5_hash
=
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
doc1
"
,
"
ok
"
:
true
,
"
rev
"
:
o
.
rev2_5
},
generateRevisionHash
(
shared
.
doc
,
shared
.
rev1_4_history
);
"
Put new revision
"
);
shared
.
rev2_5
=
"
2-
"
+
shared
.
rev2_5_hash
;
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
shared
.
rev2_5_history
=
{
o
.
tick
(
o
);
"
start
"
:
2
,
"
ids
"
:
[
shared
.
rev2_5_hash
,
shared
.
rev1_4_hash
]
};
shared
.
rev2_5_revs_info
=
tool
.
deepClone
(
shared
.
rev1_4_revs_info
);
shared
.
rev2_5_revs_info
.
unshift
({
"
rev
"
:
shared
.
rev2_5
,
"
status
"
:
"
available
"
});
return
jio
.
put
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
put
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev2_5
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Put new revision
"
);
// __/__
// __/__
// / | \
// / | \
...
@@ -321,43 +395,67 @@
...
@@ -321,43 +395,67 @@
// 2-3 2-5
// 2-3 2-5
// putAttachment to inexistent document
// putAttachment to inexistent document
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc2
"
,
"
_id
"
:
"
doc2
"
,
"
_mime
type
"
:
"
text/plain
"
,
"
_content_
type
"
:
"
text/plain
"
,
"
_data
"
:
"
doc 2 - attachment 1
"
,
"
_data
"
:
"
doc 2 - attachment 1
"
,
"
_attachment
"
:
"
attachment1
"
"
_attachment
"
:
"
attachment1
"
};
};
o
.
rev_hash
=
generateRevisionHash
(
o
.
doc
,
{
"
start
"
:
0
,
"
ids
"
:
[]});
shared
.
rev_hash
=
generateRevisionHash
(
shared
.
doc
,
{
o
.
rev
=
"
1-
"
+
o
.
rev_hash
;
"
start
"
:
0
,
o
.
spy
(
o
,
"
value
"
,
"
ids
"
:
[]
{
"
ok
"
:
true
,
"
id
"
:
"
doc2
"
,
"
attachment
"
:
"
attachment1
"
,
"
rev
"
:
o
.
rev
},
});
"
Put an attachment to an inexistent document
"
);
shared
.
rev
=
"
1-
"
+
shared
.
rev_hash
;
o
.
jio
.
putAttachment
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
return
jio
.
putAttachment
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
attachment
"
:
"
attachment1
"
,
"
id
"
:
"
doc2
"
,
"
method
"
:
"
putAttachment
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Put an attachment to an inexistent document
"
);
// putAttachment
// putAttachment
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_mime
type
"
:
"
text/plain
"
,
"
_content_
type
"
:
"
text/plain
"
,
"
_data
"
:
"
doc 1 - attachment 1
"
,
"
_data
"
:
"
doc 1 - attachment 1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_rev
"
:
o
.
rev2_5
"
_rev
"
:
shared
.
rev2_5
};
};
o
.
rev3_6_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev2_5_history
);
shared
.
attmt1_digest
=
"
sha256-7b6f6ec759b90a0d2aea0b2a6172544c904c6722
"
+
o
.
rev3_6
=
"
3-
"
+
o
.
rev3_6_hash
;
"
1a04fb871477825db92c42ff
"
;
o
.
rev3_6_history
=
deepClone
(
o
.
rev2_5_history
);
shared
.
rev3_6_hash
=
o
.
rev3_6_history
.
start
+=
1
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev2_5_history
);
o
.
rev3_6_history
.
ids
.
unshift
(
o
.
rev3_6_hash
);
shared
.
rev3_6
=
"
3-
"
+
shared
.
rev3_6_hash
;
o
.
rev3_6_revs_info
=
deepClone
(
o
.
rev2_5_revs_info
);
shared
.
rev3_6_history
=
tool
.
deepClone
(
shared
.
rev2_5_history
);
o
.
rev3_6_revs_info
.
unshift
({
"
rev
"
:
o
.
rev3_6
,
"
status
"
:
"
available
"
});
shared
.
rev3_6_history
.
start
+=
1
;
o
.
spy
(
o
,
"
value
"
,
{
shared
.
rev3_6_history
.
ids
.
unshift
(
shared
.
rev3_6_hash
);
"
ok
"
:
true
,
shared
.
rev3_6_revs_info
=
tool
.
deepClone
(
shared
.
rev2_5_revs_info
);
"
id
"
:
"
doc1
"
,
shared
.
rev3_6_revs_info
.
unshift
({
"
rev
"
:
shared
.
rev3_6
,
"
status
"
:
"
available
"
});
return
jio
.
putAttachment
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
attachment
"
:
"
attachment1
"
,
"
attachment
"
:
"
attachment1
"
,
"
rev
"
:
o
.
rev3_6
"
id
"
:
"
doc1
"
,
"
method
"
:
"
putAttachment
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev3_6
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Put an attachment to the first document
"
);
},
"
Put an attachment to the first document
"
);
o
.
jio
.
putAttachment
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// __/__
// __/__
// / | \
// / | \
...
@@ -368,55 +466,73 @@
...
@@ -368,55 +466,73 @@
// 3-6+a1
// 3-6+a1
// get document
// get document
o
.
doc
=
{
return
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
});
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev3_6
,
"
_rev
"
:
shared
.
rev3_6
,
"
_revisions
"
:
o
.
rev3_6_history
,
"
_revisions
"
:
shared
.
rev3_6_history
,
"
_revs_info
"
:
o
.
rev3_6_revs_info
,
"
_revs_info
"
:
shared
.
rev3_6_revs_info
,
"
_conflicts
"
:
[
o
.
rev2_3
,
o
.
rev1_1
],
"
_conflicts
"
:
[
shared
.
rev2_3
,
shared
.
rev1_1
],
"
_attachments
"
:
{
"
_attachments
"
:
{
"
attachment1
"
:
{
"
attachment1
"
:
{
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
content_type
"
:
"
text/plain
"
,
"
content_type
"
:
"
text/plain
"
,
"
digest
"
:
"
md5-0505c1fb6aae02dd1695d33841726564
"
"
digest
"
:
shared
.
attmt1_digest
}
}
},
},
"
title
"
:
"
put new revision
"
"
title
"
:
"
put new revision
"
};
},
"
Get document, the winner
"
);
o
.
spy
(
o
,
"
value
"
,
o
.
doc
,
"
Get document, the winner
"
);
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
},
o
.
f
);
o
.
tick
(
o
);
// get
attachment
// get winner
attachment
o
.
doc
=
{
return
jio
.
getAttachment
(
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_attachment
"
:
"
attachment1
"
"
_attachment
"
:
"
attachment1
"
};
});
o
.
spy
(
o
,
"
value
"
,
"
doc 1 - attachment 1
"
,
"
Get the winner's attachment
"
);
o
.
jio
.
getAttachment
(
o
.
doc
,
o
.
f
);
}).
then
(
function
(
answer
)
{
o
.
tick
(
o
);
return
tool
.
readBlobAsBinaryString
(
answer
.
data
);
}).
then
(
function
(
event
)
{
deepEqual
(
event
.
target
.
result
,
"
doc 1 - attachment 1
"
,
"
Get the winner's attachment
"
);
// put document
// put document
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev3_6
,
"
_rev
"
:
shared
.
rev3_6
,
"
title
"
:
"
Put revision, attachment must be copied
"
"
title
"
:
"
Put revision, attachment must be copied
"
};
};
o
.
rev4_7_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev3_6_history
);
shared
.
rev4_7_hash
=
o
.
rev4_7
=
"
4-
"
+
o
.
rev4_7_hash
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev3_6_history
);
o
.
rev4_7_history
=
deepClone
(
o
.
rev3_6_history
);
shared
.
rev4_7
=
"
4-
"
+
shared
.
rev4_7_hash
;
o
.
rev4_7_history
.
start
+=
1
;
shared
.
rev4_7_history
=
tool
.
deepClone
(
shared
.
rev3_6_history
);
o
.
rev4_7_history
.
ids
.
unshift
(
o
.
rev4_7_hash
);
shared
.
rev4_7_history
.
start
+=
1
;
o
.
rev4_7_revs_info
=
deepClone
(
o
.
rev3_6_revs_info
);
shared
.
rev4_7_history
.
ids
.
unshift
(
shared
.
rev4_7_hash
);
o
.
rev4_7_revs_info
.
unshift
({
"
rev
"
:
o
.
rev4_7
,
"
status
"
:
"
available
"
});
shared
.
rev4_7_revs_info
=
tool
.
deepClone
(
shared
.
rev3_6_revs_info
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev4_7
},
shared
.
rev4_7_revs_info
.
unshift
({
"
Update document, attachment should be copied
"
);
"
rev
"
:
shared
.
rev4_7
,
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
"
status
"
:
"
available
"
o
.
tick
(
o
);
});
return
jio
.
put
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
put
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev4_7
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Update document, attachment should be copied
"
);
// __/__
// __/__
// / | \
// / | \
...
@@ -429,62 +545,77 @@
...
@@ -429,62 +545,77 @@
// 4-7+a1
// 4-7+a1
// get document, attachment must be copied
// get document, attachment must be copied
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev4_7
,
"
_rev
"
:
shared
.
rev4_7
,
"
title
"
:
o
.
doc
.
title
,
"
title
"
:
shared
.
doc
.
title
,
"
_attachments
"
:
{
"
_attachments
"
:
{
"
attachment1
"
:
{
"
attachment1
"
:
{
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
content_type
"
:
"
text/plain
"
,
"
content_type
"
:
"
text/plain
"
,
"
digest
"
:
"
md5-0505c1fb6aae02dd1695d33841726564
"
"
digest
"
:
shared
.
attmt1_digest
}
}
},
},
"
_conflicts
"
:
[
o
.
rev2_3
,
o
.
rev1_1
],
"
_conflicts
"
:
[
shared
.
rev2_3
,
shared
.
rev1_1
],
"
_revisions
"
:
o
.
rev4_7_history
,
"
_revisions
"
:
shared
.
rev4_7_history
,
"
_revs_info
"
:
o
.
rev4_7_revs_info
"
_revs_info
"
:
shared
.
rev4_7_revs_info
};
};
o
.
spy
(
o
,
"
value
"
,
o
.
doc
,
"
Get the new winner document and its attachment metadata
"
);
return
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
// get attachment
}).
then
(
function
(
answer
)
{
o
.
doc
=
{
deepEqual
(
answer
.
data
,
shared
.
doc
,
"
Get the new winner document and its attachment metadata
"
);
// get winner attachment
return
jio
.
getAttachment
({
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_attachment
"
:
"
attachment1
"
"
_attachment
"
:
"
attachment1
"
};
});
o
.
spy
(
o
,
"
value
"
,
"
doc 1 - attachment 1
"
,
}).
then
(
function
(
answer
)
{
return
tool
.
readBlobAsBinaryString
(
answer
.
data
);
}).
then
(
function
(
event
)
{
deepEqual
(
event
.
target
.
result
,
"
doc 1 - attachment 1
"
,
"
Get the winner's attachment again
"
);
"
Get the winner's attachment again
"
);
o
.
jio
.
getAttachment
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// remove attachment
// remove attachment
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_rev
"
:
o
.
rev4_7
"
_rev
"
:
shared
.
rev4_7
};
};
o
.
rev5_8_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev4_7_history
);
shared
.
rev5_8_hash
=
o
.
rev5_8
=
"
5-
"
+
o
.
rev5_8_hash
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev4_7_history
);
o
.
rev5_8_history
=
deepClone
(
o
.
rev4_7_history
);
shared
.
rev5_8
=
"
5-
"
+
shared
.
rev5_8_hash
;
o
.
rev5_8_history
.
start
+=
1
;
shared
.
rev5_8_history
=
tool
.
deepClone
(
shared
.
rev4_7_history
);
o
.
rev5_8_history
.
ids
.
unshift
(
o
.
rev5_8_hash
);
shared
.
rev5_8_history
.
start
+=
1
;
o
.
rev5_8_revs_info
=
deepClone
(
o
.
rev4_7_revs_info
);
shared
.
rev5_8_history
.
ids
.
unshift
(
shared
.
rev5_8_hash
);
o
.
rev5_8_revs_info
.
unshift
({
"
rev
"
:
o
.
rev5_8
,
"
status
"
:
"
available
"
});
shared
.
rev5_8_revs_info
=
tool
.
deepClone
(
shared
.
rev4_7_revs_info
);
o
.
spy
(
o
,
"
value
"
,
{
shared
.
rev5_8_revs_info
.
unshift
({
"
ok
"
:
true
,
"
rev
"
:
shared
.
rev5_8
,
"
id
"
:
"
doc1
"
,
"
status
"
:
"
available
"
});
return
jio
.
removeAttachment
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
attachment
"
:
"
attachment1
"
,
"
attachment
"
:
"
attachment1
"
,
"
rev
"
:
o
.
rev5_8
"
id
"
:
"
doc1
"
,
"
method
"
:
"
removeAttachment
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev5_8
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Remove attachment
"
);
},
"
Remove attachment
"
);
o
.
jio
.
removeAttachment
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// __/__
// __/__
// / | \
// / | \
...
@@ -499,78 +630,116 @@
...
@@ -499,78 +630,116 @@
// 5-8
// 5-8
// get document to check attachment existence
// get document to check attachment existence
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev5_8
,
"
_rev
"
:
shared
.
rev5_8
,
"
title
"
:
"
Put revision, attachment must be copied
"
,
"
title
"
:
"
Put revision, attachment must be copied
"
,
"
_conflicts
"
:
[
o
.
rev2_3
,
o
.
rev1_1
],
"
_conflicts
"
:
[
shared
.
rev2_3
,
shared
.
rev1_1
],
"
_revisions
"
:
o
.
rev5_8_history
,
"
_revisions
"
:
shared
.
rev5_8_history
,
"
_revs_info
"
:
o
.
rev5_8_revs_info
"
_revs_info
"
:
shared
.
rev5_8_revs_info
};
};
o
.
spy
(
o
,
"
value
"
,
o
.
doc
,
"
Get the new winner document, no attachment must be provided
"
);
return
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
shared
.
doc
,
"
Get the new winner document, no attachment must be provided
"
);
// get specific document
// get specific document
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev4_7
,
"
_rev
"
:
shared
.
rev4_7
,
"
title
"
:
o
.
doc
.
title
,
"
title
"
:
shared
.
doc
.
title
,
"
_attachments
"
:
{
"
_attachments
"
:
{
"
attachment1
"
:
{
"
attachment1
"
:
{
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
length
"
:
"
doc 1 - attachment 1
"
.
length
,
"
content_type
"
:
"
text/plain
"
,
"
content_type
"
:
"
text/plain
"
,
"
digest
"
:
"
md5-0505c1fb6aae02dd1695d33841726564
"
"
digest
"
:
shared
.
attmt1_digest
}
}
},
},
"
_conflicts
"
:
[
o
.
rev2_3
,
o
.
rev1_1
],
"
_conflicts
"
:
[
shared
.
rev2_3
,
shared
.
rev1_1
],
"
_revisions
"
:
o
.
rev4_7_history
,
"
_revisions
"
:
shared
.
rev4_7_history
,
"
_revs_info
"
:
o
.
rev4_7_revs_info
"
_revs_info
"
:
shared
.
rev4_7_revs_info
};
};
o
.
spy
(
o
,
"
value
"
,
o
.
doc
,
"
Get the new winner document and its attachment metadata
"
);
return
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev4_7
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev4_7
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
shared
.
doc
,
"
Get specific revision and its attachment metadata
"
);
// get inexistent attachment
// get inexistent attachment
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent winner attachment
"
+
return
reverse
(
jio
.
getAttachment
({
"
-> 404 Not Found
"
);
"
_id
"
:
"
doc1
"
,
o
.
jio
.
get
({
"
_id
"
:
"
doc1/attachment1
"
},
o
.
f
);
"
_attachment
"
:
"
attachment1
"
o
.
tick
(
o
);
}));
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
attachment
"
:
"
attachment1
"
,
"
error
"
:
"
not_found
"
,
"
id
"
:
"
doc1
"
,
"
message
"
:
"
Unable to get an inexistent attachment
"
,
"
method
"
:
"
getAttachment
"
,
"
reason
"
:
"
missing
"
,
"
result
"
:
"
error
"
,
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
},
"
Get inexistent winner attachment -> 404 Not Found
"
);
// get specific attachment
// get specific attachment
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_attachment
"
:
"
attachment1
"
,
"
_rev
"
:
o
.
rev3_6
"
_rev
"
:
shared
.
rev3_6
};
};
o
.
spy
(
o
,
"
value
"
,
"
doc 1 - attachment 1
"
,
"
Get a specific attachment
"
);
return
jio
.
getAttachment
(
shared
.
doc
);
o
.
jio
.
getAttachment
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
return
tool
.
readBlobAsBinaryString
(
answer
.
data
);
}).
then
(
function
(
event
)
{
deepEqual
(
event
.
target
.
result
,
"
doc 1 - attachment 1
"
,
"
Get a specific attachment
"
);
// remove specific document and conflict
// remove specific document and conflict
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev1_1
};
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev1_1
};
// generate with deleted_flag
// generate with deleted_flag
o
.
rev2_9_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev1_1_history
,
true
);
shared
.
rev2_9_hash
=
o
.
rev2_9
=
"
2-
"
+
o
.
rev2_9_hash
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev1_1_history
,
true
);
o
.
rev2_9_history
=
deepClone
(
o
.
rev1_1_history
);
shared
.
rev2_9
=
"
2-
"
+
shared
.
rev2_9_hash
;
o
.
rev2_9_history
.
start
+=
1
;
shared
.
rev2_9_history
=
tool
.
deepClone
(
shared
.
rev1_1_history
);
o
.
rev2_9_history
.
ids
.
unshift
(
o
.
rev2_9_hash
);
shared
.
rev2_9_history
.
start
+=
1
;
o
.
rev2_9_revs_info
=
deepClone
(
o
.
rev1_1_revs_info
);
shared
.
rev2_9_history
.
ids
.
unshift
(
shared
.
rev2_9_hash
);
o
.
rev2_9_revs_info
.
unshift
({
"
rev
"
:
o
.
rev2_9
,
"
status
"
:
"
deleted
"
});
shared
.
rev2_9_revs_info
=
tool
.
deepClone
(
shared
.
rev1_1_revs_info
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev2_9
},
shared
.
rev2_9_revs_info
.
unshift
({
"
Remove specific document, and one conflict
"
);
"
rev
"
:
shared
.
rev2_9
,
o
.
jio
.
remove
(
o
.
doc
,
o
.
f
);
"
status
"
:
"
deleted
"
o
.
tick
(
o
);
});
return
jio
.
remove
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
remove
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev2_9
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Remove specific document, and one conflict
"
);
// __/___
// __/___
// / | \
// / | \
...
@@ -585,18 +754,31 @@
...
@@ -585,18 +754,31 @@
// 5-8
// 5-8
// remove specific document and conflict
// remove specific document and conflict
o
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev2_3
};
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
shared
.
rev2_3
};
o
.
rev3_10_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev2_3_history
,
true
);
shared
.
rev3_10_hash
=
o
.
rev3_10
=
"
3-
"
+
o
.
rev3_10_hash
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev2_3_history
,
true
);
o
.
rev3_10_history
=
deepClone
(
o
.
rev2_3_history
);
shared
.
rev3_10
=
"
3-
"
+
shared
.
rev3_10_hash
;
o
.
rev3_10_history
.
start
+=
1
;
shared
.
rev3_10_history
=
tool
.
deepClone
(
shared
.
rev2_3_history
);
o
.
rev3_10_history
.
ids
.
unshift
(
o
.
rev3_10_hash
);
shared
.
rev3_10_history
.
start
+=
1
;
o
.
rev3_10_revs_info
=
deepClone
(
o
.
rev2_3_revs_info
);
shared
.
rev3_10_history
.
ids
.
unshift
(
shared
.
rev3_10_hash
);
o
.
rev3_10_revs_info
.
unshift
({
"
rev
"
:
o
.
rev3_10
,
"
status
"
:
"
deleted
"
});
shared
.
rev3_10_revs_info
=
tool
.
deepClone
(
shared
.
rev2_3_revs_info
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev3_10
},
shared
.
rev3_10_revs_info
.
unshift
({
"
Remove specific document, and one conflict
"
);
"
rev
"
:
shared
.
rev3_10
,
o
.
jio
.
remove
(
o
.
doc
,
o
.
f
);
"
status
"
:
"
deleted
"
o
.
tick
(
o
);
});
return
jio
.
remove
(
shared
.
doc
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
remove
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev3_10
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Remove anther specific document, and one conflict
"
);
// ___/____
// ___/____
// / | \
// / | \
...
@@ -611,33 +793,46 @@
...
@@ -611,33 +793,46 @@
// 5-8
// 5-8
// get document no more conflict
// get document no more conflict
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev5_8
,
"
_rev
"
:
shared
.
rev5_8
,
"
title
"
:
"
Put revision, attachment must be copied
"
,
"
title
"
:
"
Put revision, attachment must be copied
"
,
"
_revisions
"
:
o
.
rev5_8_history
,
"
_revisions
"
:
shared
.
rev5_8_history
,
"
_revs_info
"
:
o
.
rev5_8_revs_info
"
_revs_info
"
:
shared
.
rev5_8_revs_info
};
};
o
.
spy
(
o
,
"
value
"
,
o
.
doc
,
"
Get the new winner document, no more conflicts
"
);
return
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
});
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
shared
.
doc
,
"
Get the new winner document, no more conflicts
"
);
// remove document
// remove document
o
.
doc
=
{
shared
.
doc
=
{
"
_id
"
:
"
doc1
"
,
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
o
.
rev5_8
"
_rev
"
:
shared
.
rev5_8
};
};
o
.
rev6_11_hash
=
generateRevisionHash
(
o
.
doc
,
o
.
rev5_8_history
,
true
);
shared
.
rev6_11_hash
=
o
.
rev6_11
=
"
6-
"
+
o
.
rev6_11_hash
;
generateRevisionHash
(
shared
.
doc
,
shared
.
rev5_8_history
,
true
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev6_11
},
shared
.
rev6_11
=
"
6-
"
+
shared
.
rev6_11_hash
;
"
Remove the last document
"
);
o
.
jio
.
remove
(
o
.
doc
,
o
.
f
);
return
jio
.
remove
(
shared
.
doc
);
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
remove
"
,
"
result
"
:
"
success
"
,
"
rev
"
:
shared
.
rev6_11
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Remove the last document
"
);
// ___/____
// ___/____
// / | \
// / | \
...
@@ -654,51 +849,84 @@
...
@@ -654,51 +849,84 @@
// D6-11
// D6-11
// get inexistent document
// get inexistent document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent document -> 404 Not Found
"
);
return
reverse
(
jio
.
get
({
"
_id
"
:
"
doc3
"
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc3
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revisions
"
:
true
"
revisions
"
:
true
},
o
.
f
);
}));
o
.
tick
(
o
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
error
"
:
"
not_found
"
,
"
id
"
:
"
doc3
"
,
"
message
"
:
"
Document not found
"
,
"
method
"
:
"
get
"
,
"
reason
"
:
"
missing
"
,
"
result
"
:
"
error
"
,
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
},
"
Get inexistent document -> 404 Not Found
"
);
// get specific deleted document
// get specific deleted document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get deleted document -> 404 Not Found
"
);
return
reverse
(
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
rev
"
:
shared
.
rev3_10
},
{
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
,
"
rev
"
:
o
.
rev3_10
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
}));
o
.
tick
(
o
);
// get specific deleted document
}).
then
(
function
(
answer
)
{
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get deleted document -> 404 Not Found
"
);
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
deepEqual
(
answer
,
{
"
error
"
:
"
not_found
"
,
"
id
"
:
"
doc1
"
,
"
message
"
:
"
Document not found
"
,
"
method
"
:
"
get
"
,
"
reason
"
:
"
deleted
"
,
"
result
"
:
"
error
"
,
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
},
"
Get specific deleted document -> 404 Not Found
"
);
// get deleted document
return
reverse
(
jio
.
get
({
"
_id
"
:
"
doc1
"
},
{
"
conflicts
"
:
true
,
"
conflicts
"
:
true
,
"
revs
"
:
true
,
"
revs
"
:
true
,
"
revs_info
"
:
true
"
revs_info
"
:
true
},
o
.
f
);
}));
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
}).
then
(
function
(
answer
)
{
};
deepEqual
(
answer
,
{
"
error
"
:
"
not_found
"
,
"
id
"
:
"
doc1
"
,
"
message
"
:
"
Document not found
"
,
"
method
"
:
"
get
"
,
"
reason
"
:
"
deleted
"
,
"
result
"
:
"
error
"
,
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
},
"
Get deleted document -> 404 Not Found
"
);
}).
fail
(
unexpectedError
).
always
(
start
);
}
test
(
"
[Revision + Local Storage] Scenario
"
,
function
()
{
test
(
"
[Revision + Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorage
(
this
,
{
testReplicateRevisionStorage
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevloc
"
,
"
username
"
:
"
ureprevloc
"
,
"
application_name
"
:
"
areprevloc
"
"
mode
"
:
"
memory
"
}
}
}]
}]
});
});
});
});
test
(
"
[Replicate Revision + Revision + Local Storage] Scenario
"
,
function
()
{
test
(
"
[Replicate Revision + Revision + Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorage
(
this
,
{
testReplicateRevisionStorage
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
...
@@ -707,34 +935,34 @@
...
@@ -707,34 +935,34 @@
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
urepreprevloc
"
,
"
username
"
:
"
urepreprevloc
"
,
"
application_name
"
:
"
arepreprevloc
"
"
mode
"
:
"
memory
"
}
}
}]
}]
}]
}]
});
});
});
});
test
(
"
2x [Revision + Local Storage] Scenario
"
,
function
()
{
test
(
"
2x [Revision + Local Storage] Scenario
"
,
function
()
{
testReplicateRevisionStorage
(
this
,
{
testReplicateRevisionStorage
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevlocloc1
"
,
"
username
"
:
"
ureprevlocloc1
"
,
"
application_name
"
:
"
areprevlocloc1
"
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
ureprevlocloc2
"
,
"
username
"
:
"
ureprevlocloc2
"
,
"
application_name
"
:
"
areprevlocloc2
"
"
mode
"
:
"
memory
"
}
}
}]
}]
});
});
});
});
test
(
"
2x [Replicate Rev + 2x [Rev + Local]] Scenario
"
,
function
()
{
test
(
"
2x [Replicate Rev + 2x [Rev + Local]] Scenario
"
,
function
()
{
testReplicateRevisionStorage
(
this
,
{
testReplicateRevisionStorage
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
...
@@ -743,14 +971,14 @@
...
@@ -743,14 +971,14 @@
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
urepreprevloc1
"
,
"
username
"
:
"
urepreprevloc1
"
,
"
application_name
"
:
"
arepreprevloc1
"
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
urepreprevloc2
"
,
"
username
"
:
"
urepreprevloc2
"
,
"
application_name
"
:
"
arepreprevloc2
"
"
mode
"
:
"
memory
"
}
}
}]
}]
},
{
},
{
...
@@ -760,253 +988,336 @@
...
@@ -760,253 +988,336 @@
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
urepreprevloc3
"
,
"
username
"
:
"
urepreprevloc3
"
,
"
application_name
"
:
"
arepreprevloc3
"
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
urepreprevloc4
"
,
"
username
"
:
"
urepreprevloc4
"
,
"
application_name
"
:
"
arepreprevloc4
"
"
mode
"
:
"
memory
"
}
}
}]
}]
}]
}]
});
});
});
});
function
replicateStorageSynchronisationGenerator
(
function
replicateStorageSynchronisationGenerator
(
jio_description
)
{
that
,
description
,
index
)
{
/*jslint unparam: true */
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
(
description
);
var
shared
=
{},
jio
,
jio_leaves
=
[];
o
.
localpath1
=
"
jio/localstorage/usyncreprevlocloc1/
"
+
index
;
shared
.
workspace
=
{};
o
.
localpath2
=
"
jio/localstorage/usyncreprevlocloc2/
"
+
index
;
jio
=
jIO
.
createJIO
(
jio_description
,
{
"
workspace
"
:
shared
.
workspace
});
o
.
localpath3
=
"
jio/localstorage/usyncreprevlocloc3/
"
+
index
;
o
.
localpath4
=
"
jio/localstorage/usyncreprevlocloc4/
"
+
index
;
function
leavesAction
(
action
,
storage_description
)
{
var
i
;
if
(
storage_description
.
type
===
"
replicaterevision
"
)
{
// it is the replicate revision storage tree
for
(
i
=
0
;
i
<
storage_description
.
storage_list
.
length
;
i
+=
1
)
{
leavesAction
(
action
,
storage_description
.
storage_list
[
i
]);
}
}
else
if
(
storage_description
.
type
===
"
revision
"
)
{
// it is the revision storage tree
leavesAction
(
action
,
storage_description
.
sub_storage
);
}
else
{
// it is the storage tree leaf
action
(
storage_description
);
}
}
leavesAction
(
function
(
storage_description
)
{
jio_leaves
.
push
(
jIO
.
createJIO
(
storage_description
,
{
"
workspace
"
:
shared
.
workspace
}));
},
jio_description
);
if
(
jio_leaves
.
length
!==
4
)
{
// please make a jio description with 4 localstorage
ok
(
false
,
"
More or less then 4 localstorage were provided
"
);
return
;
}
jio_leaves
.
run
=
function
(
method
,
argument
)
{
var
i
,
promises
=
[];
for
(
i
=
0
;
i
<
this
.
length
;
i
+=
1
)
{
promises
[
i
]
=
this
[
i
][
method
].
apply
(
this
[
i
],
argument
);
}
return
RSVP
.
all
(
promises
);
};
jio_leaves
.
get
=
function
()
{
return
this
.
run
(
"
get
"
,
arguments
);
};
jio_leaves
.
put
=
function
()
{
return
this
.
run
(
"
put
"
,
arguments
);
};
jio_leaves
.
allDocs
=
function
()
{
return
this
.
run
(
"
allDocs
"
,
arguments
);
};
stop
();
// add documents to localstorage
// add documents to localstorage
o
.
doctree1_1
=
{
shared
.
doctree1_1
=
{
"
_id
"
:
"
doc1.revision_tree.json
"
,
"
_id
"
:
"
doc1.revision_tree.json
"
,
"
children
"
:
[{
"
children
"
:
JSON
.
stringify
(
[{
"
rev
"
:
"
1-111
"
,
"
rev
"
:
"
1-111
"
,
"
status
"
:
"
available
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
"
children
"
:
[]
}]
}]
)
};
};
o
.
doc1_1
=
{
"
_id
"
:
"
doc1.1-111
"
,
"
title
"
:
"
A
"
};
shared
.
doc1_1
=
{
"
_id
"
:
"
doc1.1-111
"
,
"
title
"
:
"
A
"
};
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
,
jio_leaves
.
put
(
shared
.
doctree1_1
).
then
(
function
()
{
o
.
doctree1_1
);
return
jio_leaves
.
put
(
shared
.
doc1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath2
+
"
/doc1.revision_tree.json
"
,
}).
then
(
function
()
{
o
.
doctree1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath3
+
"
/doc1.revision_tree.json
"
,
o
.
doctree1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath4
+
"
/doc1.revision_tree.json
"
,
o
.
doctree1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/
"
+
o
.
doc1_1
.
_id
,
o
.
doc1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath2
+
"
/
"
+
o
.
doc1_1
.
_id
,
o
.
doc1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath3
+
"
/
"
+
o
.
doc1_1
.
_id
,
o
.
doc1_1
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath4
+
"
/
"
+
o
.
doc1_1
.
_id
,
o
.
doc1_1
);
// no synchronisation
// no synchronisation
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
},
return
jio
.
check
({
"
_id
"
:
"
doc1
"
});
"
Check document
"
);
o
.
jio
.
check
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
,
"
rev
"
:
"
1-111
"
},
}).
then
(
function
(
answer
)
{
"
Check document with revision
"
);
o
.
jio
.
check
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
"
1-111
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
},
deepEqual
(
answer
,
{
"
Repair document
"
);
"
id
"
:
"
doc1
"
,
o
.
jio
.
repair
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
"
method
"
:
"
check
"
,
o
.
tick
(
o
);
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Check document
"
);
return
jio
.
check
({
"
_id
"
:
"
doc1
"
,
"
_rev
"
:
"
1-111
"
});
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
check
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Check document with revision
"
);
return
jio
.
repair
({
"
_id
"
:
"
doc1
"
});
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
repair
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Repair document
"
);
// check documents from localstorage
// check documents from localstorage
deepEqual
(
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.revision_tree.json
"
});
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
),
o
.
doctree1_1
,
}).
then
(
function
(
answers
)
{
"
Check revision tree 1, no synchro done
"
var
i
;
);
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
deepEqual
(
deepEqual
(
answers
[
i
].
data
,
shared
.
doctree1_1
,
"
Check revision tree
"
+
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath2
+
"
/doc1.revision_tree.json
"
),
i
+
"
, no syncho done
"
);
o
.
doctree1_1
,
}
"
Check revision tree 2, no synchro done
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.revision_tree.json
"
),
o
.
doctree1_1
,
"
Check revision tree 3, no synchro done
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath4
+
"
/doc1.revision_tree.json
"
),
o
.
doctree1_1
,
"
Check revision tree 4, no synchro done
"
);
// add documents to localstorage
// add documents to localstorage
o
.
doctree2_2
=
deepClone
(
o
.
doctree1_1
);
shared
.
doctree2_2
=
tool
.
deepClone
(
shared
.
doctree1_1
);
o
.
doctree2_2
.
children
[
0
].
children
.
push
({
shared
.
doctree2_2
.
children
=
JSON
.
parse
(
shared
.
doctree2_2
.
children
);
shared
.
doctree2_2
.
children
[
0
].
children
.
push
({
"
rev
"
:
"
2-222
"
,
"
rev
"
:
"
2-222
"
,
"
status
"
:
"
available
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
"
children
"
:
[]
});
});
o
.
doc2_2
=
{
shared
.
doctree2_2
.
children
=
JSON
.
stringify
(
shared
.
doctree2_2
.
children
);
shared
.
doc2_2
=
{
"
_id
"
:
"
doc1.2-222
"
,
"
_id
"
:
"
doc1.2-222
"
,
"
title
"
:
"
B
"
,
"
title
"
:
"
B
"
,
"
_attachments
"
:
{
"
_attachments
"
:
{
"
haha
"
:
{
"
haha
"
:
{
"
length
"
:
3
,
"
length
"
:
3
,
"
digest
"
:
"
md5-900150983cd24fb0d6963f7d28e17f72
"
,
"
digest
"
:
"
sha256-ba7816bf8f01cfea414140de5dae2223b00361a3
"
+
"
96177a9cb410ff61f20015ad
"
,
"
content_type
"
:
"
text/plain
"
"
content_type
"
:
"
text/plain
"
}
}
}
}
};
};
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
,
o
.
doctree2_2
);
return
jio_leaves
[
0
].
put
(
shared
.
doctree2_2
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/
"
+
o
.
doc2_2
.
_id
,
o
.
doc2_2
);
}).
then
(
function
()
{
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/
"
+
o
.
doc2_2
.
_id
+
return
jio_leaves
[
0
].
put
(
shared
.
doc2_2
);
"
/haha
"
,
"
abc
"
);
}).
then
(
function
()
{
return
jio_leaves
[
0
].
putAttachment
({
"
_id
"
:
shared
.
doc2_2
.
_id
,
"
_attachment
"
:
"
haha
"
,
"
_data
"
:
"
abc
"
,
"
_content_type
"
:
"
text/plain
"
});
}).
then
(
function
()
{
// document synchronisation without conflict
// document synchronisation without conflict
o
.
spy
(
o
,
"
status
"
,
41
,
"
Check document
"
);
return
reverse
(
jio
.
check
({
"
_id
"
:
"
doc1
"
}));
o
.
jio
.
check
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
o
.
tick
(
o
,
50000
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
},
}).
then
(
function
(
answer
)
{
"
Repair document
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
o
.
tick
(
o
,
50000
);
// check documents from localstorage
deepEqual
(
answer
,
{
deepEqual
(
"
error
"
:
"
conflict
"
,
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
),
"
id
"
:
"
doc1
"
,
o
.
doctree2_2
,
"
message
"
:
"
Some documents are different in the sub storages
"
,
"
Check revision tree 1, no synchro done
"
"
method
"
:
"
check
"
,
);
"
reason
"
:
"
Storage contents differ
"
,
deepEqual
(
"
result
"
:
"
error
"
,
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath2
+
"
/doc1.revision_tree.json
"
),
"
status
"
:
409
,
o
.
doctree2_2
,
"
statusText
"
:
"
Conflict
"
"
Check revision tree 2, revision synchro done
"
},
"
Check document
"
);
);
deepEqual
(
return
jio
.
repair
({
"
_id
"
:
"
doc1
"
});
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.revision_tree.json
"
),
o
.
doctree2_2
,
}).
then
(
function
(
answer
)
{
"
Check revision tree 3, revision synchro done
"
);
deepEqual
(
answer
,
{
deepEqual
(
"
id
"
:
"
doc1
"
,
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.2-222
"
),
"
method
"
:
"
repair
"
,
o
.
doc2_2
,
"
result
"
:
"
success
"
,
"
Check document 3
"
"
status
"
:
204
,
);
"
statusText
"
:
"
No Content
"
deepEqual
(
},
"
Repair document
"
);
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.2-222/haha
"
),
"
abc
"
,
// check document trees
"
Check attachment 3
"
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.revision_tree.json
"
});
);
deepEqual
(
}).
then
(
function
(
answers
)
{
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath4
+
"
/doc1.revision_tree.json
"
),
var
i
;
o
.
doctree2_2
,
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
"
Check revision tree 4, revision synchro done
"
deepEqual
(
answers
[
i
].
data
,
shared
.
doctree2_2
,
"
Check revision tree
"
+
);
i
+
"
,
"
+
(
i
?
""
:
"
no
"
)
+
"
synchro done
"
);
}
// check document 2
return
jio_leaves
[
2
].
get
({
"
_id
"
:
"
doc1.2-222
"
});
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
shared
.
doc2_2
,
"
Check document 2
"
);
// check attachment 2
return
jio_leaves
[
2
].
getAttachment
({
"
_id
"
:
"
doc1.2-222
"
,
"
_attachment
"
:
"
haha
"
});
}).
then
(
function
(
answer
)
{
return
tool
.
readBlobAsBinaryString
(
answer
.
data
);
}).
then
(
function
(
event
)
{
deepEqual
(
event
.
target
.
result
,
"
abc
"
,
"
Check attachment 2
"
);
// add documents to localstorage
// add documents to localstorage
o
.
doctree2_3
=
deepClone
(
o
.
doctree2_2
);
shared
.
doctree2_3
=
tool
.
deepClone
(
shared
.
doctree2_2
);
o
.
doctree2_3
.
children
[
0
].
children
.
unshift
({
shared
.
doctree2_3
.
children
=
JSON
.
parse
(
shared
.
doctree2_3
.
children
);
shared
.
doctree2_3
.
children
[
0
].
children
.
unshift
({
"
rev
"
:
"
2-223
"
,
"
rev
"
:
"
2-223
"
,
"
status
"
:
"
available
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
"
children
"
:
[]
});
});
o
.
doc2_3
=
{
"
_id
"
:
"
doc1.2-223
"
,
"
title
"
:
"
C
"
};
shared
.
doctree2_3
.
children
=
JSON
.
stringify
(
shared
.
doctree2_3
.
children
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
,
shared
.
doc2_3
=
{
"
_id
"
:
"
doc1.2-223
"
,
"
title
"
:
"
C
"
};
o
.
doctree2_3
);
util
.
jsonlocalstorage
.
setItem
(
o
.
localpath1
+
"
/
"
+
o
.
doc2_3
.
_id
,
o
.
doc2_3
);
return
jio_leaves
[
0
].
put
(
shared
.
doctree2_3
);
}).
then
(
function
()
{
return
jio_leaves
[
0
].
put
(
shared
.
doc2_3
);
}).
then
(
function
()
{
// document synchronisation with conflict
// document synchronisation with conflict
o
.
spy
(
o
,
"
status
"
,
41
,
"
Check document
"
);
return
reverse
(
jio
.
check
({
"
_id
"
:
"
doc1
"
}));
o
.
jio
.
check
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
o
.
tick
(
o
,
50000
);
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
,
{
"
error
"
:
"
conflict
"
,
"
id
"
:
"
doc1
"
,
"
message
"
:
"
Some documents are different in the sub storages
"
,
"
method
"
:
"
check
"
,
"
reason
"
:
"
Storage contents differ
"
,
"
result
"
:
"
error
"
,
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
},
"
Check document
"
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
doc1
"
},
return
jio
.
repair
({
"
_id
"
:
"
doc1
"
});
"
Repair document
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
}).
then
(
function
(
answer
)
{
o
.
tick
(
o
,
50000
);
deepEqual
(
answer
,
{
"
id
"
:
"
doc1
"
,
"
method
"
:
"
repair
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
Repair document
"
);
// check documents from localstorage
// check documents from localstorage
deepEqual
(
return
jio_leaves
.
get
({
"
_id
"
:
"
doc1.revision_tree.json
"
});
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath1
+
"
/doc1.revision_tree.json
"
),
o
.
doctree2_3
,
"
Check revision tree 1, rev synchro
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath2
+
"
/doc1.revision_tree.json
"
),
o
.
doctree2_3
,
"
Check revision tree 2, rev synchro
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.revision_tree.json
"
),
o
.
doctree2_3
,
"
Check revision tree 3, rev synchro
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath3
+
"
/doc1.2-223
"
),
o
.
doc2_3
,
"
Check document 3
"
);
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
o
.
localpath4
+
"
/doc1.revision_tree.json
"
),
o
.
doctree2_3
,
"
Check revision tree 4, rev synchro
"
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
}).
then
(
function
(
answers
)
{
var
i
;
for
(
i
=
0
;
i
<
answers
.
length
;
i
+=
1
)
{
deepEqual
(
answers
[
i
].
data
,
shared
.
doctree2_3
,
"
Check revision tree
"
+
i
+
"
,
"
+
(
i
?
""
:
"
no
"
)
+
"
synchro done
"
);
}
// check document 2
return
jio_leaves
[
2
].
get
({
"
_id
"
:
"
doc1.2-223
"
});
}).
then
(
function
(
answer
)
{
deepEqual
(
answer
.
data
,
shared
.
doc2_3
,
"
Check document 2
"
);
}).
fail
(
unexpectedError
).
always
(
start
);
}
}
test
(
"
Storage Synchronisation (Repair) 4x [Rev + Local]
"
,
function
()
{
test
(
"
Storage Synchronisation (Repair) 4x [Rev + Local]
"
,
function
()
{
replicateStorageSynchronisationGenerator
(
this
,
{
replicateStorageSynchronisationGenerator
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc1
"
,
"
username
"
:
"
usyncreprevlocloc1
"
,
"
application_name
"
:
"
1
"
"
application_name
"
:
"
1
"
,
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc2
"
,
"
username
"
:
"
usyncreprevlocloc2
"
,
"
application_name
"
:
"
1
"
"
application_name
"
:
"
1
"
,
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc3
"
,
"
username
"
:
"
usyncreprevlocloc3
"
,
"
application_name
"
:
"
1
"
"
application_name
"
:
"
1
"
,
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc4
"
,
"
username
"
:
"
usyncreprevlocloc4
"
,
"
application_name
"
:
"
1
"
"
application_name
"
:
"
1
"
,
"
mode
"
:
"
memory
"
}
}
}]
}]
}
,
"
1
"
);
});
});
});
test
(
test
(
"
Storage Synchronisation (Repair) 2x [Rep 2x [Rev + Local]]
"
,
"
Storage Synchronisation (Repair) 2x [Rep 2x [Rev + Local]]
"
,
function
()
{
function
()
{
replicateStorageSynchronisationGenerator
(
this
,
{
replicateStorageSynchronisationGenerator
({
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
"
storage_list
"
:
[{
"
storage_list
"
:
[{
"
type
"
:
"
replicaterevision
"
,
"
type
"
:
"
replicaterevision
"
,
...
@@ -1015,14 +1326,16 @@
...
@@ -1015,14 +1326,16 @@
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc1
"
,
"
username
"
:
"
usyncreprevlocloc1
"
,
"
application_name
"
:
"
2
"
"
application_name
"
:
"
2
"
,
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc2
"
,
"
username
"
:
"
usyncreprevlocloc2
"
,
"
application_name
"
:
"
2
"
"
application_name
"
:
"
2
"
,
"
mode
"
:
"
memory
"
}
}
}]
}]
},
{
},
{
...
@@ -1032,18 +1345,20 @@
...
@@ -1032,18 +1345,20 @@
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc3
"
,
"
username
"
:
"
usyncreprevlocloc3
"
,
"
application_name
"
:
"
2
"
"
application_name
"
:
"
2
"
,
"
mode
"
:
"
memory
"
}
}
},
{
},
{
"
type
"
:
"
revision
"
,
"
type
"
:
"
revision
"
,
"
sub_storage
"
:
{
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
type
"
:
"
local
"
,
"
username
"
:
"
usyncreprevlocloc4
"
,
"
username
"
:
"
usyncreprevlocloc4
"
,
"
application_name
"
:
"
2
"
"
application_name
"
:
"
2
"
,
"
mode
"
:
"
memory
"
}
}
}]
}]
}]
}]
}
,
"
2
"
);
});
}
}
);
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment