Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
officejs
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
officejs
Commits
91a84412
Commit
91a84412
authored
Aug 14, 2012
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update ConflictManagerStorage and Jio tests
parent
36e09bbc
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
965 additions
and
542 deletions
+965
-542
OfficeJS/src/jio.storage/conflictmanagerstorage.js
OfficeJS/src/jio.storage/conflictmanagerstorage.js
+347
-231
OfficeJS/test/jiotests.js
OfficeJS/test/jiotests.js
+618
-311
No files found.
OfficeJS/src/jio.storage/conflictmanagerstorage.js
View file @
91a84412
...
...
@@ -30,90 +30,79 @@ var newConflictManagerStorage = function ( spec, my ) {
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
metadata_only
=
false
;
cloned_option
.
max_retry
=
command
.
getOption
(
'
max_retry
'
)
||
3
;
cloned_option
.
error
=
error
;
cloned_option
.
success
=
success
;
var
newcommand
=
that
.
newCommand
(
'
loadDocument
'
,{
path
:
path
,
option
:
cloned_option
});
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
that
.
addJob
(
'
get
'
,
priv
.
secondstorage_spec
,
path
,
cloned_option
,
success
,
error
);
};
priv
.
saveMetadataToDistant
=
function
(
command
,
path
,
content
,
success
,
error
)
{
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
error
=
error
;
cloned_option
.
success
=
success
;
var
newcommand
=
that
.
newCommand
(
'
saveDocument
'
,{
path
:
path
,
content
:
JSON
.
stringify
(
content
),
option
:
cloned_option
});
// newcommand.setMaxRetry (0); // inf
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
// max_retry:0 // inf
that
.
addJob
(
'
put
'
,
priv
.
secondstorage_spec
,
{
_id
:
path
,
content
:
JSON
.
stringify
(
content
)},
command
.
cloneOption
(),
success
,
error
);
};
priv
.
saveNewRevision
=
function
(
command
,
path
,
content
,
success
,
error
)
{
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
error
=
error
;
cloned_option
.
success
=
success
;
var
newcommand
=
that
.
newCommand
(
'
saveDocument
'
,{
path
:
path
,
content
:
content
,
option
:
cloned_option
});
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
that
.
addJob
(
'
put
'
,
priv
.
secondstorage_spec
,{
_id
:
path
,
content
:
content
},
command
.
cloneOption
(),
success
,
error
);
};
priv
.
loadRevision
=
function
(
command
,
path
,
success
,
error
)
{
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
error
=
error
;
cloned_option
.
success
=
success
;
var
newcommand
=
that
.
newCommand
(
'
loadDocument
'
,{
path
:
path
,
option
:
cloned_option
});
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
that
.
addJob
(
'
get
'
,
priv
.
secondstorage_spec
,
path
,
command
.
cloneOption
(),
success
,
error
);
};
priv
.
deleteAFile
=
function
(
command
,
path
,
success
,
error
)
{
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
max_retry
=
0
;
// inf
cloned_option
.
error
=
error
;
cloned_option
.
success
=
success
;
var
newcommand
=
that
.
newCommand
(
'
removeDocument
'
,{
path
:
path
,
option
:
cloned_option
});
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
that
.
addJob
(
'
remove
'
,
priv
.
secondstorage_spec
,{
_id
:
path
},
command
.
cloneOption
(),
success
,
error
);
};
priv
.
chooseARevision
=
function
(
metadata
)
{
var
tmp_last_modified
=
0
,
ret_rev
=
''
;
for
(
var
rev
in
metadata
)
{
var
tmp_last_modified
=
0
,
ret_rev
=
''
,
rev
;
for
(
rev
in
metadata
)
{
if
(
tmp_last_modified
<
metadata
[
rev
].
last_modified
)
{
metadata
[
rev
].
_
last_modified
)
{
tmp_last_modified
=
metadata
[
rev
].
last_modified
;
metadata
[
rev
].
_
last_modified
;
ret_rev
=
rev
;
}
}
return
ret_rev
;
};
priv
.
solveConflict
=
function
(
path
,
content
,
option
)
{
priv
.
_revs
=
function
(
metadata
,
revision
)
{
if
(
metadata
[
revision
])
{
return
{
start
:
metadata
[
revision
].
_revisions
.
length
,
ids
:
metadata
[
revision
].
_revisions
};
}
else
{
return
null
;
}
};
priv
.
_revs_info
=
function
(
metadata
)
{
var
k
,
l
=
[];
for
(
k
in
metadata
)
{
l
.
push
({
rev
:
k
,
status
:(
metadata
[
k
]?(
metadata
[
k
].
_deleted
?
'
deleted
'
:
'
available
'
):
'
missing
'
)
});
}
return
l
;
};
priv
.
solveConflict
=
function
(
doc
,
option
,
param
)
{
var
o
=
{},
am
=
priv
.
newAsyncModule
(),
command
=
option
.
command
,
metadata_file_path
=
pa
th
+
'
.metadata
'
,
command
=
param
.
command
,
metadata_file_path
=
pa
ram
.
docid
+
'
.metadata
'
,
current_revision
=
''
,
current_revision_file_path
=
''
,
metadata_file_content
=
null
,
on_conflict
=
false
,
conflict_object
=
{},
on_remove
=
option
.
deleted
,
previous_revision
=
option
.
previous_revision
,
previous_revision_object
=
option
.
revision_remove_object
||
{},
previous_revision_content_object
=
previous_revision_object
[
previous_revision
]
||
{},
on_conflict
=
false
,
conflict_object
=
{
total_rows
:
0
,
rows
:[]},
on_remove
=
param
.
_deleted
,
previous_revision
=
param
.
previous_revision
,
previous_revision_content_object
=
null
,
now
=
new
Date
(),
failerror
;
...
...
@@ -126,11 +115,13 @@ var newConflictManagerStorage = function ( spec, my ) {
metadata_file_content
=
JSON
.
parse
(
result
.
content
);
// set current revision
current_revision
=
(
previous_revision_number
+
1
)
+
'
-
'
+
hex_sha256
(
''
+
content
+
hex_sha256
(
''
+
doc
.
content
+
previous_revision
+
JSON
.
stringify
(
metadata_file_content
));
current_revision_file_path
=
pa
th
+
'
.
'
+
current_revision_file_path
=
pa
ram
.
docid
+
'
.
'
+
current_revision
;
previous_revision_content_object
=
metadata_file_content
[
previous_revision
]
||
{};
if
(
!
on_remove
)
{
am
.
wait
(
o
,
'
saveMetadataOnDistant
'
,
1
);
am
.
call
(
o
,
'
saveNewRevision
'
);
...
...
@@ -143,7 +134,7 @@ var newConflictManagerStorage = function ( spec, my ) {
};
o
.
saveNewRevision
=
function
(){
priv
.
saveNewRevision
(
command
,
current_revision_file_path
,
content
,
command
,
current_revision_file_path
,
doc
.
content
,
function
(
result
)
{
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
},
function
(
error
)
{
...
...
@@ -152,18 +143,20 @@ var newConflictManagerStorage = function ( spec, my ) {
);
};
o
.
previousUpdateMetadata
=
function
()
{
for
(
var
prev_rev
in
previous_revision_object
)
{
delete
metadata_file_content
[
prev_rev
];
var
i
;
for
(
i
=
0
;
i
<
param
.
key
.
length
;
i
+=
1
)
{
delete
metadata_file_content
[
param
.
key
[
i
]];
}
am
.
call
(
o
,
'
checkForConflicts
'
);
};
o
.
checkForConflicts
=
function
()
{
for
(
var
rev
in
metadata_file_content
)
{
var
rev
;
for
(
rev
in
metadata_file_content
)
{
var
revision_index
;
on_conflict
=
true
;
failerror
=
{
status
:
20
,
statusText
:
'
Conflict
'
,
status
:
409
,
error
:
'
conflict
'
,
statusText
:
'
Conflict
'
,
reason
:
'
document update conflict
'
,
message
:
'
There is one or more conflicts
'
};
break
;
...
...
@@ -171,22 +164,29 @@ var newConflictManagerStorage = function ( spec, my ) {
am
.
call
(
o
,
'
updateMetadata
'
);
};
o
.
updateMetadata
=
function
(){
var
revision_history
,
id
=
''
;
id
=
current_revision
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
revision_history
=
previous_revision_content_object
.
_revisions
;
revision_history
.
unshift
(
id
);
metadata_file_content
[
current_revision
]
=
{
creation_date
:
previous_revision_content_object
.
creation_date
||
_creation_date
:
previous_revision_content_object
.
_creation_date
||
now
.
getTime
(),
last_modified
:
now
.
getTime
(),
conflict
:
on_conflict
,
deleted
:
on_remove
_last_modified
:
now
.
getTime
(),
_revisions
:
revision_history
,
_conflict
:
on_conflict
,
_deleted
:
on_remove
};
if
(
on_conflict
)
{
conflict_object
=
priv
.
createConflictObject
(
command
,
metadata_file_content
,
current_revision
);
}
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
};
o
.
saveMetadataOnDistant
=
function
(){
priv
.
saveMetadataToDistant
(
command
,
metadata_file_path
,
metadata_file_content
,
command
,
metadata_file_path
,
metadata_file_content
,
function
(
result
)
{
am
.
call
(
o
,
'
deleteAllConflictingRevision
'
);
if
(
on_conflict
)
{
...
...
@@ -200,58 +200,115 @@ var newConflictManagerStorage = function ( spec, my ) {
);
};
o
.
deleteAllConflictingRevision
=
function
(){
for
(
var
prev_rev
in
previous_revision_object
)
{
var
i
;
for
(
i
=
0
;
i
<
param
.
key
.
length
;
i
+=
1
)
{
priv
.
deleteAFile
(
command
,
pa
th
+
'
.
'
+
prev_rev
,
empty_fun
,
empty_fun
);
command
,
pa
ram
.
docid
+
'
.
'
+
param
.
key
[
i
],
empty_fun
,
empty_fun
);
}
};
o
.
success
=
function
(){
var
a
=
{
ok
:
true
,
id
:
param
.
docid
,
rev
:
current_revision
};
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
if
(
option
.
success
)
{
option
.
success
({
revision
:
current_revision
});}
if
(
option
.
revs
)
{
a
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
option
.
revs_info
)
{
a
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
option
.
conflicts
)
{
a
.
conflicts
=
conflict_object
;
}
param
.
success
(
a
);
};
o
.
error
=
function
(
error
){
var
gooderror
=
error
||
failerror
||
{};
if
(
on_conflict
)
{
gooderror
.
conflict_object
=
conflict_object
;
var
err
=
error
||
failerror
||
{
status
:
0
,
statusText
:
'
Unknown
'
,
error
:
'
unknown_error
'
,
message
:
'
Unknown error.
'
,
reason
:
'
unknown error
'
};
if
(
current_revision
)
{
err
.
rev
=
current_revision
;
}
if
(
option
.
revs
)
{
err
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
option
.
revs_info
)
{
err
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
option
.
conflicts
)
{
err
.
conflicts
=
conflict_object
;
}
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
if
(
option
.
error
)
{
option
.
error
(
gooderror
);}
param
.
error
(
err
);
};
am
.
call
(
o
,
'
getDistantMetadata
'
);
};
priv
.
createConflictObject
=
function
(
command
,
metadata
,
revision
)
{
var
cloned_command
=
command
.
clone
();
var
conflict_object
=
{
path
:
command
.
getPath
(),
revision
:
revision
,
revision_object
:
metadata
,
getConflictRevisionList
:
function
()
{
return
this
.
revision_object
;
},
solveConflict
:
function
(
content
,
option
)
{
if
(
typeof
content
===
'
undefined
'
)
{
option
=
option
||
{};
option
.
deleted
=
true
;
}
else
if
(
typeof
content
===
'
object
'
)
{
option
=
content
;
option
.
deleted
=
true
;
return
{
total_rows
:
1
,
rows
:[
priv
.
createConflictRow
(
command
,
command
.
getDocId
(),
metadata
,
revision
)]
};
};
priv
.
getParam
=
function
(
list
)
{
var
param
=
{},
i
=
0
;
if
(
typeof
list
[
i
]
===
'
string
'
)
{
param
.
content
=
list
[
i
];
i
++
;
}
if
(
typeof
list
[
i
]
===
'
object
'
)
{
param
.
options
=
list
[
i
];
i
++
;
}
else
{
option
=
option
||
{};
option
.
deleted
=
false
;
content
=
content
||
''
;
param
.
options
=
{};
}
option
.
previous_revision
=
this
.
revision
;
option
.
revision_remove_object
=
this
.
revision_object
;
option
.
command
=
cloned_command
;
param
.
callback
=
function
(
err
,
val
){};
param
.
success
=
function
(
val
)
{
param
.
callback
(
undefined
,
val
);
};
param
.
error
=
function
(
err
)
{
param
.
callback
(
err
,
undefined
);
};
if
(
typeof
list
[
i
]
===
'
function
'
)
{
if
(
typeof
list
[
i
+
1
]
===
'
function
'
)
{
param
.
success
=
list
[
i
];
param
.
error
=
list
[
i
+
1
];
}
else
{
param
.
callback
=
list
[
i
];
}
}
return
param
;
};
priv
.
createConflictRow
=
function
(
command
,
docid
,
metadata
,
revision
)
{
var
row
=
{
id
:
docid
,
key
:[],
value
:{
_solveConflict
:
function
(
/*content, option, success, error*/
)
{
var
param
=
{},
got
=
priv
.
getParam
(
arguments
);
if
(
got
.
content
===
undefined
)
{
param
.
_deleted
=
true
;
}
else
{
param
.
_deleted
=
false
;
}
param
.
success
=
got
.
success
;
param
.
error
=
got
.
error
;
param
.
previous_revision
=
revision
;
param
.
docid
=
docid
;
param
.
key
=
row
.
key
;
param
.
command
=
command
.
clone
();
return
priv
.
solveConflict
(
this
.
path
,
content
,
option
{
_id
:
docid
,
content
:
got
.
content
,
_rev
:
revision
},
got
.
options
,
param
);
}
};
return
conflict_object
;
}},
k
;
for
(
k
in
metadata
)
{
row
.
key
.
push
(
k
);
}
return
row
;
};
priv
.
newAsyncModule
=
function
()
{
...
...
@@ -282,31 +339,28 @@ var newConflictManagerStorage = function ( spec, my ) {
return
async
;
};
that
.
post
=
function
(
command
)
{
that
.
put
(
command
);
};
/**
* Save a document and can manage conflicts.
* @method
saveDocumen
t
* @method
pu
t
*/
that
.
saveDocumen
t
=
function
(
command
)
{
that
.
pu
t
=
function
(
command
)
{
var
o
=
{},
am
=
priv
.
newAsyncModule
(),
metadata_file_path
=
command
.
get
Path
()
+
'
.metadata
'
,
metadata_file_path
=
command
.
get
DocId
()
+
'
.metadata
'
,
current_revision
=
''
,
current_revision_file_path
=
''
,
metadata_file_content
=
null
,
on_conflict
=
false
,
conflict_object
=
{},
previous_revision
=
command
.
get
Option
(
'
previous_revision
'
)
,
previous_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
on_conflict
=
false
,
conflict_object
=
{
total_rows
:
0
,
rows
:[]
},
previous_revision
=
command
.
get
DocInfo
(
'
_rev
'
)
||
'
0
'
,
previous_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
previous_revision
,
now
=
new
Date
(),
failerror
;
if
(
!
previous_revision
)
{
return
setTimeout
(
function
()
{
that
.
error
({
status
:
0
,
statusText
:
'
Parameter missing
'
,
message
:
'
Need a previous revision.
'
});
});
}
o
.
getDistantMetadata
=
function
(){
priv
.
getDistantMetadata
(
command
,
metadata_file_path
,
...
...
@@ -316,10 +370,10 @@ var newConflictManagerStorage = function ( spec, my ) {
metadata_file_content
=
JSON
.
parse
(
result
.
content
);
// set current revision
current_revision
=
(
previous_revision_number
+
1
)
+
'
-
'
+
hex_sha256
(
''
+
command
.
getContent
()
+
hex_sha256
(
''
+
command
.
get
Doc
Content
()
+
previous_revision
+
JSON
.
stringify
(
metadata_file_content
));
current_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
current_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
current_revision
;
am
.
wait
(
o
,
'
saveMetadataOnDistant
'
,
1
);
am
.
call
(
o
,
'
saveNewRevision
'
);
...
...
@@ -327,8 +381,8 @@ var newConflictManagerStorage = function ( spec, my ) {
},
function
(
error
)
{
if
(
error
.
status
===
404
)
{
current_revision
=
'
1-
'
+
hex_sha256
(
command
.
getContent
());
current_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
hex_sha256
(
command
.
get
Doc
Content
());
current_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
current_revision
;
am
.
wait
(
o
,
'
saveMetadataOnDistant
'
,
1
);
am
.
call
(
o
,
'
saveNewRevision
'
);
...
...
@@ -341,7 +395,7 @@ var newConflictManagerStorage = function ( spec, my ) {
};
o
.
saveNewRevision
=
function
(){
priv
.
saveNewRevision
(
command
,
current_revision_file_path
,
command
.
getContent
(),
command
,
current_revision_file_path
,
command
.
get
Doc
Content
(),
function
(
result
)
{
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
},
function
(
error
)
{
...
...
@@ -350,13 +404,14 @@ var newConflictManagerStorage = function ( spec, my ) {
);
};
o
.
checkForConflicts
=
function
()
{
for
(
var
rev
in
metadata_file_content
)
{
var
rev
;
for
(
rev
in
metadata_file_content
)
{
if
(
rev
!==
previous_revision
)
{
on_conflict
=
true
;
failerror
=
{
status
:
20
,
statusText
:
'
Conflict
'
,
message
:
'
There is one or more conflicts
'
status
:
409
,
error
:
'
conflict
'
,
statusText
:
'
Conflict
'
,
reason
:
'
document update conflict
'
,
message
:
'
Document update conflict.
'
};
break
;
}
...
...
@@ -364,41 +419,47 @@ var newConflictManagerStorage = function ( spec, my ) {
am
.
call
(
o
,
'
updateMetadata
'
);
};
o
.
createMetadata
=
function
(){
var
id
=
current_revision
;
id
=
id
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
metadata_file_content
=
{};
metadata_file_content
[
current_revision
]
=
{
creation_date
:
now
.
getTime
(),
last_modified
:
now
.
getTime
(),
conflict
:
false
,
deleted
:
false
_creation_date
:
now
.
getTime
(),
_last_modified
:
now
.
getTime
(),
_revisions
:
[
id
],
_conflict
:
false
,
_deleted
:
false
};
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
};
o
.
updateMetadata
=
function
(){
var
previous_creation_date
;
var
previous_creation_date
,
revision_history
=
[],
id
=
''
;
if
(
metadata_file_content
[
previous_revision
])
{
previous_creation_date
=
metadata_file_content
[
previous_revision
].
creation_date
;
previous_revision
].
_creation_date
;
revision_history
=
metadata_file_content
[
previous_revision
].
_revisions
;
delete
metadata_file_content
[
previous_revision
];
}
id
=
current_revision
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
revision_history
.
unshift
(
id
);
metadata_file_content
[
current_revision
]
=
{
creation_date
:
previous_creation_date
||
now
.
getTime
(),
last_modified
:
now
.
getTime
(),
conflict
:
on_conflict
,
deleted
:
false
_creation_date
:
previous_creation_date
||
now
.
getTime
(),
_last_modified
:
now
.
getTime
(),
_revisions
:
revision_history
,
_conflict
:
on_conflict
,
_deleted
:
false
};
if
(
on_conflict
)
{
conflict_object
=
priv
.
createConflictObject
(
command
,
metadata_file_content
,
current_revision
command
,
metadata_file_content
,
current_revision
);
}
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
};
o
.
saveMetadataOnDistant
=
function
(){
priv
.
saveMetadataToDistant
(
command
,
metadata_file_path
,
metadata_file_content
,
command
,
metadata_file_path
,
metadata_file_content
,
function
(
result
)
{
am
.
call
(
o
,
'
deletePreviousRevision
'
);
if
(
on_conflict
)
{
...
...
@@ -418,44 +479,65 @@ var newConflictManagerStorage = function ( spec, my ) {
empty_fun
,
empty_fun
);
}
};
o
.
success
=
function
(){
o
.
success
=
function
()
{
var
a
=
{
ok
:
true
,
id
:
command
.
getDocId
(),
rev
:
current_revision
};
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
that
.
success
({
revision
:
current_revision
});
if
(
command
.
getOption
(
'
revs
'
))
{
a
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
command
.
getOption
(
'
revs_info
'
))
{
a
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
a
.
conflicts
=
conflict_object
;
}
that
.
success
(
a
);
};
o
.
error
=
function
(
error
){
var
gooderror
=
error
||
failerror
||
{
status
:
0
,
statusText
:
'
Unknown
'
,
message
:
'
Unknown error.
'
};
if
(
on_conflict
)
{
gooderror
.
conflict_object
=
conflict_object
;
o
.
error
=
function
(
error
)
{
var
err
=
error
||
failerror
||
{
status
:
0
,
statusText
:
'
Unknown
'
,
error
:
'
unknown_error
'
,
message
:
'
Unknown error.
'
,
reason
:
'
unknown error
'
};
if
(
current_revision
)
{
err
.
rev
=
current_revision
;
}
if
(
command
.
getOption
(
'
revs
'
))
{
err
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
command
.
getOption
(
'
revs_info
'
))
{
err
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
err
.
conflicts
=
conflict_object
;
}
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
that
.
error
(
gooderro
r
);
that
.
error
(
er
r
);
};
am
.
call
(
o
,
'
getDistantMetadata
'
);
};
};
// end put
/**
* Load a document from several storages, and send the first retreived
* document.
* @method
loadDocumen
t
* @method
ge
t
*/
that
.
loadDocumen
t
=
function
(
command
)
{
that
.
ge
t
=
function
(
command
)
{
var
o
=
{},
am
=
priv
.
newAsyncModule
(),
metadata_file_path
=
command
.
get
Path
()
+
'
.metadata
'
,
current_revision
=
command
.
getOption
(
'
rev
ision
'
)
||
''
,
metadata_file_path
=
command
.
get
DocId
()
+
'
.metadata
'
,
current_revision
=
command
.
getOption
(
'
rev
'
)
||
''
,
metadata_file_content
=
null
,
metadata_only
=
command
.
getOption
(
'
metadata_only
'
),
on_conflict
=
false
,
conflict_object
=
{},
on_conflict
=
false
,
conflict_object
=
{
total_rows
:
0
,
rows
:[]
},
now
=
new
Date
(),
doc
=
{
name
:
command
.
getPath
()},
doc
=
{
_id
:
command
.
getDocId
()},
call404
=
function
(
message
)
{
am
.
call
(
o
,
'
error
'
,[{
status
:
404
,
statusText
:
'
Not Found
'
,
message
:
message
status
:
404
,
statusText
:
'
Not Found
'
,
error
:
'
not_found
'
,
message
:
message
,
reason
:
message
}]);
};
...
...
@@ -482,12 +564,18 @@ var newConflictManagerStorage = function ( spec, my ) {
}
else
{
current_revision
=
priv
.
chooseARevision
(
metadata_file_content
);
}
doc
.
last_modified
=
metadata_file_content
[
current_revision
].
last_modified
;
doc
.
creation_date
=
metadata_file_content
[
current_revision
].
creation_date
;
doc
.
revision
=
current_revision
;
doc
.
revision_object
=
metadata_file_content
;
doc
.
_last_modified
=
metadata_file_content
[
current_revision
].
_last_modified
;
doc
.
_creation_date
=
metadata_file_content
[
current_revision
].
_creation_date
;
doc
.
_rev
=
current_revision
;
if
(
command
.
getOption
(
'
revs
'
))
{
doc
.
_revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
command
.
getOption
(
'
revs_info
'
))
{
doc
.
_revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
metadata_only
)
{
am
.
call
(
o
,
'
success
'
);
}
else
{
...
...
@@ -496,11 +584,11 @@ var newConflictManagerStorage = function ( spec, my ) {
};
o
.
loadRevision
=
function
(){
if
(
!
current_revision
||
metadata_file_content
[
current_revision
].
deleted
)
{
metadata_file_content
[
current_revision
].
_
deleted
)
{
return
call404
(
'
Document has been removed.
'
);
}
priv
.
loadRevision
(
command
,
doc
.
name
+
'
.
'
+
current_revision
,
command
,
doc
.
_id
+
'
.
'
+
current_revision
,
function
(
result
)
{
doc
.
content
=
result
.
content
;
am
.
call
(
o
,
'
success
'
);
...
...
@@ -518,7 +606,9 @@ var newConflictManagerStorage = function ( spec, my ) {
metadata_file_content
,
current_revision
);
doc
.
conflict_object
=
conflict_object
;
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
doc
.
_conflicts
=
conflict_object
;
}
am
.
call
(
o
,
'
success
'
);
};
...
...
@@ -543,35 +633,30 @@ var newConflictManagerStorage = function ( spec, my ) {
/**
* Get a document list from several storages, and returns the first
* retreived document list.
* @method
getDocumentList
* @method
allDocs
*/
that
.
getDocumentList
=
function
(
command
)
{
that
.
allDocs
=
function
(
command
)
{
var
o
=
{},
am
=
priv
.
newAsyncModule
(),
metadata_only
=
command
.
getOption
(
'
metadata_only
'
),
result_list
=
[],
nb_loaded_file
=
0
,
success_count
=
0
,
success_max
=
0
;
o
.
retreiveList
=
function
()
{
var
cloned_option
=
command
.
cloneOption
();
cloned_option
.
metadata_only
=
true
;
cloned_option
.
error
=
function
(
error
)
{
am
.
call
(
o
,
'
error
'
,[
error
]);
};
cloned_option
.
success
=
function
(
result
)
{
var
cloned_option
=
command
.
cloneOption
(),
success
=
function
(
result
)
{
am
.
call
(
o
,
'
filterTheList
'
,[
result
]);
},
error
=
function
(
error
)
{
am
.
call
(
o
,
'
error
'
,[
error
]);
};
var
newcommand
=
that
.
newCommand
(
'
getDocumentList
'
,{
path
:
command
.
getPath
(),
option
:
cloned_option
});
that
.
addJob
(
that
.
newStorage
(
priv
.
secondstorage_spec
),
newcommand
);
cloned_option
.
metadata_only
=
true
;
that
.
addJob
(
'
allDocs
'
,
priv
.
secondstorage_spec
,
null
,
cloned_option
,
success
,
error
);
};
o
.
filterTheList
=
function
(
result
)
{
var
i
;
success_max
++
;
for
(
i
=
0
;
i
<
result
.
length
;
i
+=
1
)
{
var
splitname
=
result
[
i
].
name
.
split
(
'
.
'
)
||
[];
for
(
i
=
0
;
i
<
result
.
total_rows
;
i
+=
1
)
{
var
splitname
=
result
.
rows
[
i
].
id
.
split
(
'
.
'
)
||
[];
if
(
splitname
.
length
>
0
&&
splitname
[
splitname
.
length
-
1
]
===
'
metadata
'
)
{
success_max
++
;
...
...
@@ -587,7 +672,7 @@ var newConflictManagerStorage = function ( spec, my ) {
function
(
data
)
{
data
=
JSON
.
parse
(
data
.
content
);
var
revision
=
priv
.
chooseARevision
(
data
);
if
(
!
data
[
revision
].
deleted
)
{
if
(
!
data
[
revision
].
_
deleted
)
{
am
.
call
(
o
,
'
loadFile
'
,
[
path
,
revision
,
data
]
...
...
@@ -602,15 +687,22 @@ var newConflictManagerStorage = function ( spec, my ) {
};
o
.
loadFile
=
function
(
path
,
revision
,
data
)
{
var
doc
=
{
name
:
path
,
last_modified
:
data
[
revision
].
last_modified
,
creation_date
:
data
[
revision
].
creation_date
,
revision
:
revision
,
revision_object
:
data
};
if
(
data
[
revision
].
conflict
)
{
doc
.
conflict_object
=
priv
.
createConflictObject
(
id
:
path
,
key
:
path
,
value
:{
_last_modified
:
data
[
revision
].
_last_modified
,
_creation_date
:
data
[
revision
].
_creation_date
,
_rev
:
revision
}
};
if
(
command
.
getOption
(
'
revs_info
'
))
{
doc
.
value
.
_revs_info
=
priv
.
_revs_info
(
data
,
revision
);
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
if
(
data
[
revision
].
_conflict
)
{
doc
.
value
.
_conflicts
=
priv
.
createConflictObject
(
command
,
data
,
revision
);
}
else
{
doc
.
value
.
_conflicts
=
{
total_rows
:
0
,
rows
:[]};
}
}
if
(
!
metadata_only
)
{
priv
.
loadRevision
(
...
...
@@ -631,7 +723,7 @@ var newConflictManagerStorage = function ( spec, my ) {
success_count
++
;
if
(
success_count
>=
success_max
)
{
am
.
end
();
that
.
success
(
result_list
);
that
.
success
(
{
total_rows
:
result_list
.
length
,
rows
:
result_list
}
);
}
};
o
.
error
=
function
(
error
){
...
...
@@ -639,33 +731,26 @@ var newConflictManagerStorage = function ( spec, my ) {
that
.
error
(
error
);
};
am
.
call
(
o
,
'
retreiveList
'
);
};
};
// end allDocs
/**
* Remove a document from several storages.
* @method remove
Document
* @method remove
*/
that
.
remove
Document
=
function
(
command
)
{
that
.
remove
=
function
(
command
)
{
var
o
=
{},
am
=
priv
.
newAsyncModule
(),
metadata_file_path
=
command
.
get
Path
()
+
'
.metadata
'
,
metadata_file_path
=
command
.
get
DocId
()
+
'
.metadata
'
,
current_revision
=
''
,
current_revision_file_path
=
''
,
metadata_file_content
=
null
,
on_conflict
=
false
,
conflict_object
=
{},
previous_revision
=
command
.
getOption
(
'
rev
ision
'
)
,
previous_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
on_conflict
=
false
,
conflict_object
=
{
total_rows
:
0
,
rows
:[]
},
previous_revision
=
command
.
getOption
(
'
rev
'
)
||
'
0
'
,
previous_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
previous_revision
,
now
=
new
Date
(),
failerror
;
if
(
!
previous_revision
)
{
return
setTimeout
(
function
()
{
that
.
error
({
status
:
0
,
statusText
:
'
Parameter missing
'
,
message
:
'
Need a revision.
'
});
});
}
o
.
getDistantMetadata
=
function
(){
priv
.
getDistantMetadata
(
command
,
metadata_file_path
,
...
...
@@ -674,21 +759,25 @@ var newConflictManagerStorage = function ( spec, my ) {
if
(
previous_revision
===
'
last
'
)
{
previous_revision
=
priv
.
chooseARevision
(
metadata_file_content
);
previous_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
previous_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
previous_revision
;
}
var
previous_revision_number
=
parseInt
(
previous_revision
.
split
(
'
-
'
)[
0
],
10
);
parseInt
(
previous_revision
.
split
(
'
-
'
)[
0
],
10
)
||
0
;
// set current revision
current_revision
=
(
previous_revision_number
+
1
)
+
'
-
'
+
hex_sha256
(
''
+
previous_revision
+
JSON
.
stringify
(
metadata_file_content
));
current_revision_file_path
=
command
.
get
Path
()
+
'
.
'
+
current_revision_file_path
=
command
.
get
DocId
()
+
'
.
'
+
current_revision
;
am
.
call
(
o
,
'
checkForConflicts
'
);
},
function
(
error
)
{
if
(
error
.
status
===
404
)
{
am
.
call
(
o
,
'
success
'
,[
'
0
'
]);
am
.
call
(
o
,
'
error
'
,[{
status
:
404
,
statusText
:
'
Not Found
'
,
error
:
'
not_found
'
,
reason
:
'
missing
'
,
message
:
'
Document not found.
'
}]);
}
else
{
am
.
call
(
o
,
'
error
'
,[
error
]);
}
...
...
@@ -696,12 +785,13 @@ var newConflictManagerStorage = function ( spec, my ) {
);
};
o
.
checkForConflicts
=
function
()
{
for
(
var
rev
in
metadata_file_content
)
{
var
rev
;
for
(
rev
in
metadata_file_content
)
{
if
(
rev
!==
previous_revision
)
{
on_conflict
=
true
;
failerror
=
{
status
:
20
,
statusText
:
'
Conflict
'
,
status
:
409
,
error
:
'
conflict
'
,
statusText
:
'
Conflict
'
,
reason
:
'
document update conflict
'
,
message
:
'
There is one or more conflicts
'
};
break
;
...
...
@@ -710,31 +800,35 @@ var newConflictManagerStorage = function ( spec, my ) {
am
.
call
(
o
,
'
updateMetadata
'
);
};
o
.
updateMetadata
=
function
(){
var
previous_creation_date
;
var
previous_creation_date
,
revision_history
=
[],
id
=
''
;
if
(
metadata_file_content
[
previous_revision
])
{
previous_creation_date
=
metadata_file_content
[
previous_revision
].
creation_date
;
previous_revision
].
_creation_date
;
revision_history
=
metadata_file_content
[
previous_revision
].
_revisions
;
delete
metadata_file_content
[
previous_revision
];
}
id
=
current_revision
;
id
=
id
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
revision_history
.
unshift
(
id
);
metadata_file_content
[
current_revision
]
=
{
creation_date
:
previous_creation_date
||
now
.
getTime
(),
last_modified
:
now
.
getTime
(),
conflict
:
on_conflict
,
deleted
:
true
_creation_date
:
previous_creation_date
||
now
.
getTime
(),
_last_modified
:
now
.
getTime
(),
_revisions
:
revision_history
,
_conflict
:
on_conflict
,
_deleted
:
true
};
if
(
on_conflict
)
{
conflict_object
=
priv
.
createConflictObject
(
command
,
metadata_file_content
,
current_revision
command
,
metadata_file_content
,
current_revision
);
}
am
.
call
(
o
,
'
saveMetadataOnDistant
'
);
};
o
.
saveMetadataOnDistant
=
function
(){
priv
.
saveMetadataToDistant
(
command
,
metadata_file_path
,
metadata_file_content
,
command
,
metadata_file_path
,
metadata_file_content
,
function
(
result
)
{
am
.
call
(
o
,
'
deletePreviousRevision
'
);
if
(
on_conflict
)
{
...
...
@@ -755,23 +849,45 @@ var newConflictManagerStorage = function ( spec, my ) {
}
};
o
.
success
=
function
(
revision
){
var
a
=
{
ok
:
true
,
id
:
command
.
getDocId
(),
rev
:
revision
||
current_revision
};
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
that
.
success
({
revision
:
revision
||
current_revision
});
if
(
command
.
getOption
(
'
revs
'
))
{
a
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
command
.
getOption
(
'
revs_info
'
))
{
a
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
a
.
conflicts
=
conflict_object
;
}
that
.
success
(
a
);
};
o
.
error
=
function
(
error
){
var
gooderror
=
error
||
failerror
||
{
status
:
0
,
statusText
:
'
Unknown
'
,
message
:
'
Unknown error.
'
};
if
(
on_conflict
)
{
gooderror
.
conflict_object
=
conflict_object
;
var
err
=
error
||
failerror
||
{
status
:
0
,
statusText
:
'
Unknown
'
,
error
:
'
unknown_error
'
,
message
:
'
Unknown error.
'
,
reason
:
'
unknown error
'
};
if
(
current_revision
)
{
err
.
rev
=
current_revision
;
}
if
(
command
.
getOption
(
'
revs
'
))
{
err
.
revisions
=
priv
.
_revs
(
metadata_file_content
,
current_revision
);
}
if
(
command
.
getOption
(
'
revs_info
'
))
{
err
.
revs_info
=
priv
.
_revs_info
(
metadata_file_content
);
}
if
(
command
.
getOption
(
'
conflicts
'
))
{
err
.
conflicts
=
conflict_object
;
}
am
.
neverCall
(
o
,
'
error
'
);
am
.
neverCall
(
o
,
'
success
'
);
that
.
error
(
gooderro
r
);
that
.
error
(
er
r
);
};
am
.
call
(
o
,
'
getDistantMetadata
'
);
};
};
// end remove
return
that
;
};
...
...
OfficeJS/test/jiotests.js
View file @
91a84412
...
...
@@ -136,6 +136,56 @@ removeFileFromLocalStorage = function (user,appid,file) {
newarray
);
LocalOrCookieStorage
.
deleteItem
(
'
jio/local/
'
+
user
+
'
/
'
+
appid
+
'
/
'
+
file
.
_id
);
},
makeRevsAccordingToRevsInfo
=
function
(
revs
,
revs_info
)
{
var
i
,
j
;
for
(
i
=
0
;
i
<
revs
.
start
;
i
+=
1
)
{
for
(
j
=
0
;
j
<
revs_info
.
length
;
j
+=
1
)
{
var
id
=
revs_info
[
j
].
rev
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
if
(
revs
.
ids
[
i
]
===
id
)
{
revs
.
ids
[
i
]
=
revs_info
[
j
].
rev
.
split
(
'
-
'
)[
0
];
break
;
}
}
}
},
checkRev
=
function
(
rev
)
{
if
(
typeof
rev
===
'
string
'
)
{
if
(
parseInt
(
rev
.
split
(
'
-
'
)[
0
],
10
)
>
0
)
{
return
rev
;
}
}
return
'
ERROR: not a good revision!
'
;
},
checkConflictRow
=
function
(
row
)
{
var
fun
;
if
(
typeof
row
===
'
object
'
)
{
if
(
row
.
value
&&
typeof
row
.
value
.
_solveConflict
===
'
function
'
)
{
fun
=
row
.
value
.
_solveConflict
;
row
.
value
.
_solveConflict
=
'
function
'
;
}
}
return
fun
;
},
getHashFromRev
=
function
(
rev
)
{
var
id
=
rev
;
if
(
typeof
id
===
'
string
'
)
{
id
=
id
.
split
(
'
-
'
);
id
.
shift
();
id
=
id
.
join
(
'
-
'
);
}
return
id
;
},
revs_infoContains
=
function
(
revs_info
,
rev
)
{
var
i
;
if
(
typeof
revs_info
!==
'
object
'
)
{
return
undefined
;
}
for
(
i
=
0
;
i
<
revs_info
.
length
||
0
;
i
+=
1
)
{
if
(
revs_info
[
i
].
rev
&&
revs_info
[
i
].
rev
===
rev
)
{
return
true
;
}
}
return
false
;
};
//// end tools
...
...
@@ -1302,19 +1352,9 @@ test ('Simple methods', function () {
var
o
=
{};
o
.
clock
=
this
.
sandbox
.
useFakeTimers
();
o
.
t
=
this
;
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
function
(
res
,
value
,
message
,
before
)
{
o
.
f
=
function
(
result
)
{
if
(
res
===
'
status
'
)
{
if
(
result
&&
result
.
conflict_object
)
{
result
=
'
conflict
'
;
}
else
if
(
result
&&
typeof
result
.
status
!==
'
undefined
'
)
{
result
=
'
fail
'
;
}
else
{
result
=
'
done
'
;
}
}
if
(
before
)
{
before
(
result
);
}
deepEqual
(
result
,
value
,
message
);
o
.
spy
=
function
(
value
,
message
)
{
o
.
f
=
function
(
err
,
val
)
{
deepEqual
(
err
||
val
,
value
,
message
);
};
o
.
t
.
spy
(
o
,
'
f
'
);
};
...
...
@@ -1333,79 +1373,154 @@ test ('Simple methods', function () {
storage
:{
type
:
'
local
'
,
username
:
'
conflictmethods
'
,
applicationname
:
'
jiotests
'
}});
o
.
spy
(
'
status
'
,
'
done
'
,
'
saving "file.doc".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content1
'
,{
previous_revision
:
'
0
'
,
success
:
function
(
result
)
{
o
.
new_rev
=
result
.
revision
;
o
.
f
(
result
)
;
}
,
error
:
o
.
f
// PUT
o
.
spy
({
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
'
1
'
},
'
saving "file.doc".
'
);
o
.
jio
.
put
({
_id
:
'
file.doc
'
,
content
:
'
content1
'
},
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev1
=
val
.
rev
;
val
.
rev
=
val
.
rev
.
split
(
'
-
'
)[
0
]
;
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
o
.
spy
(
'
status
'
,
'
done
'
,
'
saving "file2.doc".
'
);
o
.
jio
.
saveDocument
(
'
file2.doc
'
,
'
yes
'
,{
previous_revision
:
'
0
'
,
success
:
o
.
f
,
error
:
o
.
f
// PUT with options
o
.
spy
({
ok
:
true
,
id
:
'
file2.doc
'
,
rev
:
'
1
'
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
1
,
ids
:[
'
1
'
]},
revs_info
:[{
rev
:
'
1
'
,
status
:
'
available
'
}]},
'
saving "file2.doc".
'
);
o
.
jio
.
put
({
_id
:
'
file2.doc
'
,
content
:
'
yes
'
},
{
revs
:
true
,
revs_info
:
true
,
conflicts
:
true
},
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev2
=
val
.
rev
;
val
.
rev
=
val
.
rev
.
split
(
'
-
'
)[
0
];
if
(
val
.
revs_info
)
{
if
(
val
.
revisions
)
{
makeRevsAccordingToRevsInfo
(
val
.
revisions
,
val
.
revs_info
);
}
val
.
revs_info
[
0
].
rev
=
val
.
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
];
}
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
o
.
spy
(
'
value
'
,{
name
:
'
file.doc
'
,
content
:
'
content1
'
,
revision
:
'
rev
'
},
'
loading "file.doc".
'
,
function
(
o
)
{
if
(
!
o
)
{
return
;
}
if
(
o
.
revision
)
{
o
.
revision
=
'
rev
'
;
}
if
(
o
.
creation_date
)
{
delete
o
.
creation_date
;
}
else
{
ok
(
false
,
'
creation date missing!
'
);
}
if
(
o
.
last_modified
)
{
delete
o
.
last_modified
;
}
else
{
ok
(
false
,
'
last modified missing!
'
);
}
if
(
o
.
revision_object
)
{
delete
o
.
revision_object
;
}
else
{
ok
(
false
,
'
revision object missing!
'
);
}
});
o
.
jio
.
loadDocument
(
'
file.doc
'
,{
success
:
o
.
f
,
error
:
o
.
f
});
// GET
o
.
get_callback
=
function
(
err
,
val
)
{
if
(
val
)
{
val
.
_rev
=
(
val
.
_rev
?
val
.
_rev
.
split
(
'
-
'
)[
0
]:
'
/
'
);
val
.
_creation_date
=
(
val
.
_creation_date
?
true
:
undefined
);
val
.
_last_modified
=
(
val
.
_last_modified
?
true
:
undefined
);
}
o
.
f
(
err
,
val
);
};
o
.
spy
({
_id
:
'
file.doc
'
,
content
:
'
content1
'
,
_rev
:
'
1
'
,
_creation_date
:
true
,
_last_modified
:
true
},
'
loading "file.doc".
'
);
o
.
jio
.
get
(
'
file.doc
'
,
o
.
get_callback
);
o
.
tick
();
// GET with options
o
.
get_callback
=
function
(
err
,
val
)
{
if
(
val
)
{
val
.
_rev
=
(
val
.
_rev
?
val
.
_rev
.
split
(
'
-
'
)[
0
]:
'
/
'
);
val
.
_creation_date
=
(
val
.
_creation_date
?
true
:
undefined
);
val
.
_last_modified
=
(
val
.
_last_modified
?
true
:
undefined
);
if
(
val
.
_revs_info
)
{
if
(
val
.
_revisions
)
{
makeRevsAccordingToRevsInfo
(
val
.
_revisions
,
val
.
_revs_info
);
}
val
.
_revs_info
[
0
].
rev
=
val
.
_revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
];
}
}
o
.
f
(
err
,
val
);
};
o
.
spy
({
_id
:
'
file2.doc
'
,
content
:
'
yes
'
,
_rev
:
'
1
'
,
_creation_date
:
true
,
_last_modified
:
true
,
_conflicts
:{
total_rows
:
0
,
rows
:[]},
_revisions
:{
start
:
1
,
ids
:[
'
1
'
]},
_revs_info
:[{
rev
:
'
1
'
,
status
:
'
available
'
}]},
'
loading "file2.doc".
'
);
o
.
jio
.
get
(
'
file2.doc
'
,{
revs
:
true
,
revs_info
:
true
,
conflicts
:
true
},
o
.
get_callback
);
o
.
tick
();
o
.
spy
(
'
value
'
,[{
name
:
'
file.doc
'
,
revision
:
'
rev
'
},
{
name
:
'
file2.doc
'
,
revision
:
'
rev
'
}],
'
getting list.
'
,
function
(
a
)
{
// allDocs
o
.
spy
({
total_rows
:
2
,
rows
:[{
id
:
'
file.doc
'
,
key
:
'
file.doc
'
,
value
:{
_rev
:
'
1
'
,
_creation_date
:
true
,
_last_modified
:
true
}
},{
id
:
'
file2.doc
'
,
key
:
'
file2.doc
'
,
value
:{
_rev
:
'
1
'
,
_creation_date
:
true
,
_last_modified
:
true
}
}]},
'
getting list.
'
);
o
.
jio
.
allDocs
(
function
(
err
,
val
)
{
if
(
val
)
{
var
i
;
if
(
!
a
)
{
return
;
}
for
(
i
=
0
;
i
<
a
.
length
;
i
+=
1
)
{
if
(
a
[
i
].
revision
)
{
a
[
i
].
revision
=
'
rev
'
;
}
if
(
a
[
i
].
creation_date
)
{
delete
a
[
i
].
creation_date
;
}
else
{
ok
(
false
,
'
creation date missing!
'
);
}
if
(
a
[
i
].
last_modified
)
{
delete
a
[
i
].
last_modified
;
}
else
{
ok
(
false
,
'
last modified missing!
'
);
}
if
(
a
[
i
].
revision_object
)
{
delete
a
[
i
].
revision_object
;
}
else
{
ok
(
false
,
'
revision object missing!
'
);
}
for
(
i
=
0
;
i
<
val
.
total_rows
;
i
+=
1
)
{
val
.
rows
[
i
].
value
.
_creation_date
=
val
.
rows
[
i
].
value
.
_creation_date
?
true
:
undefined
;
val
.
rows
[
i
].
value
.
_last_modified
=
val
.
rows
[
i
].
value
.
_last_modified
?
true
:
undefined
;
val
.
rows
[
i
].
value
.
_rev
=
val
.
rows
[
i
].
value
.
_rev
.
split
(
'
-
'
)[
0
];
}
// because the result can be disordered
if
(
a
.
length
===
2
&&
a
[
0
].
name
===
'
file2.doc
'
)
{
var
tmp
=
a
[
0
];
a
[
0
]
=
a
[
1
];
a
[
1
]
=
tmp
;
if
(
val
.
total_rows
===
2
&&
val
.
rows
[
0
].
id
===
'
file2.doc
'
)
{
var
tmp
=
val
.
rows
[
0
];
val
.
rows
[
0
]
=
val
.
rows
[
1
];
val
.
rows
[
1
]
=
tmp
;
}
}
o
.
f
(
err
,
val
);
});
o
.
jio
.
getDocumentList
(
'
.
'
,{
success
:
o
.
f
,
error
:
o
.
f
});
o
.
tick
();
o
.
spy
(
'
status
'
,
'
done
'
,
'
removing "file.doc"
'
);
o
.
jio
.
removeDocument
(
'
file.doc
'
,{
success
:
o
.
f
,
error
:
o
.
f
,
revision
:
o
.
new_rev
// remove
o
.
spy
({
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
'
2
'
},
'
removing "file.doc"
'
);
o
.
jio
.
remove
({
_id
:
'
file.doc
'
},{
rev
:
o
.
rev1
},
function
(
err
,
val
)
{
if
(
val
)
{
val
.
rev
=
val
.
rev
?
val
.
rev
.
split
(
'
-
'
)[
0
]:
undefined
;
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
o
.
spy
(
'
status
'
,
'
fail
'
,
'
loading document fail.
'
);
o
.
jio
.
loadDocument
(
'
file.doc
'
,{
success
:
o
.
f
,
error
:
function
(
error
)
{
if
(
error
.
status
===
404
)
{
o
.
f
(
error
);
}
else
{
deepEqual
(
error
,
'
{}
'
,
'
An 404 error was expected.
'
);
// remove with options
o
.
spy
({
ok
:
true
,
id
:
'
file2.doc
'
,
rev
:
'
2
'
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
2
,
ids
:[
'
2
'
,
getHashFromRev
(
o
.
rev2
)]},
revs_info
:[{
rev
:
'
2
'
,
status
:
'
deleted
'
}]
},
'
removing "file2.doc"
'
);
o
.
jio
.
remove
(
{
_id
:
'
file2.doc
'
},
{
rev
:
o
.
rev2
,
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
if
(
val
)
{
val
.
rev
=
val
.
rev
?
val
.
rev
.
split
(
'
-
'
)[
0
]:
undefined
;
if
(
val
.
revs_info
)
{
if
(
val
.
revisions
)
{
makeRevsAccordingToRevsInfo
(
val
.
revisions
,
val
.
revs_info
);
}
val
.
revs_info
[
0
].
rev
=
val
.
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
];
}
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
o
.
spy
(
404
,
'
loading document fail.
'
);
o
.
jio
.
get
(
'
file.doc
'
,
function
(
err
,
val
)
{
if
(
err
)
{
err
=
err
.
status
;
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
...
...
@@ -1417,33 +1532,9 @@ test ('Revision Conflict', function() {
var
o
=
{};
o
.
clock
=
this
.
sandbox
.
useFakeTimers
();
o
.
t
=
this
;
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
function
(
res
,
value
,
message
,
function_name
)
{
function_name
=
function_name
||
'
f
'
;
o
[
function_name
]
=
function
(
result
)
{
if
(
res
===
'
status
'
)
{
if
(
result
&&
result
.
conflict_object
)
{
result
=
'
conflict
'
;
}
else
if
(
result
&&
typeof
result
.
status
!==
'
undefined
'
)
{
result
=
'
fail
'
;
}
else
{
result
=
'
done
'
;
}
}
deepEqual
(
result
,
value
,
message
);
};
o
.
t
.
spy
(
o
,
function_name
);
};
o
.
tick
=
function
(
tick
,
function_name
)
{
function_name
=
function_name
||
'
f
'
o
.
clock
.
tick
(
tick
||
1000
);
if
(
!
o
[
function_name
].
calledOnce
)
{
if
(
o
[
function_name
].
called
)
{
ok
(
false
,
'
too much results
'
);
}
else
{
ok
(
false
,
'
no response
'
);
}
}
};
o
.
spy
=
basic_spy_function
;
o
.
tick
=
basic_tick_function
;
o
.
localNamespace
=
'
jio/local/revisionconflict/jiotests/
'
;
o
.
rev
=
{};
o
.
checkContent
=
function
(
string
,
message
)
{
...
...
@@ -1461,76 +1552,136 @@ test ('Revision Conflict', function() {
o
.
jio
=
JIO
.
newJio
({
type
:
'
conflictmanager
'
,
storage
:
o
.
secondstorage_spec
});
// create a new file
o
.
spy
(
'
status
'
,
'
done
'
,
'
new file "file.doc", revision: "0".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content1
'
,{
previous_revision
:
'
0
'
,
error
:
o
.
f
,
success
:
function
(
value
){
o
.
rev
.
first
=
value
.
revision
;
o
.
f
(
value
);
o
.
spy
(
o
,
'
value
'
,
{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
'
1
'
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revs_info
:[{
rev
:
'
1
'
,
status
:
'
available
'
}],
revisions
:{
start
:
1
,
ids
:[
'
1
'
]}},
'
new file "file.doc".
'
);
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content1
'
},
{
revs
:
true
,
revs_info
:
true
,
conflicts
:
true
},
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev
.
first
=
val
.
rev
;
val
.
rev
=
val
.
rev
?
val
.
rev
.
split
(
'
-
'
)[
0
]:
undefined
;
if
(
val
.
revs_info
)
{
if
(
val
.
revisions
)
{
makeRevsAccordingToRevsInfo
(
val
.
revisions
,
val
.
revs_info
);
}
});
o
.
tick
();
val
.
revs_info
[
0
].
rev
=
val
.
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
];
}
}
o
.
f
(
err
,
val
);
}
);
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
// modify the file
o
.
spy
(
'
status
'
,
'
done
'
,
'
modify "file.doc", revision: "
'
+
o
.
spy
(
o
,
'
value
'
,
{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
'
2
'
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
2
,
ids
:[
'
2
'
,
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
'
2
'
,
status
:
'
available
'
}]},
'
modify "file.doc", revision: "
'
+
o
.
rev
.
first
+
'
".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content2
'
,{
previous_revision
:
o
.
rev
.
first
,
error
:
o
.
f
,
success
:
function
(
v
)
{
o
.
f
(
v
);
o
.
rev
.
second
=
v
.
revision
;
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content2
'
,
_rev
:
o
.
rev
.
first
},
{
revs
:
true
,
revs_info
:
true
,
conflicts
:
true
},
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev
.
second
=
val
.
rev
;
val
.
rev
=
val
.
rev
?
val
.
rev
.
split
(
'
-
'
)[
0
]:
undefined
;
if
(
val
.
revs_info
)
{
if
(
val
.
revisions
)
{
makeRevsAccordingToRevsInfo
(
val
.
revisions
,
val
.
revs_info
);
}
});
o
.
tick
();
val
.
revs_info
[
0
].
rev
=
val
.
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
];
}
}
o
.
f
(
err
,
val
);
}
);
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
second
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
// modify the file from the second revision instead of the third
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
modify "file.doc", revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content3
'
,{
previous_revision
:
o
.
rev
.
first
,
success
:
o
.
f
,
error
:
function
(
error
)
{
o
.
conflict_object
=
error
.
conflict_object
;
o
.
f
(
error
);
o
.
rev
.
third
=
'
?
'
;
if
(
o
.
conflict_object
)
{
o
.
rev
.
third
=
o
.
conflict_object
.
revision
;
ok
(
!
o
.
conflict_object
.
revision_object
[
o
.
new_rev
],
o
.
test_message
=
'
modify "file.doc", revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content3
'
,
_rev
:
o
.
rev
.
first
},
{
revs
:
true
,
revs_info
:
true
,
conflicts
:
true
},
function
(
err
,
val
)
{
o
.
f
();
var
k
;
if
(
err
)
{
o
.
rev
.
third
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
third
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
second
,
o
.
rev
.
third
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
third
)]},
revs_info
:[{
rev
:
o
.
rev
.
second
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
third
,
status
:
'
available
'
}]
},
o
.
test_message
);
ok
(
!
revs_infoContains
(
err
.
revs_info
,
o
.
rev
.
first
),
'
check if the first revision is not include to
'
+
'
the conflict list.
'
);
ok
(
o
.
conflict_object
.
revision_object
[
o
.
conflict_object
.
revision
],
ok
(
revs_infoContains
(
err
.
revs_info
,
err
.
rev
),
'
check if the new revision is include to
'
+
'
the conflict list.
'
);
}
}
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
third
);
// loading test
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
loading "file.doc" -> conflict!
'
);
o
.
jio
.
loadDocument
(
'
file.doc
'
,{
success
:
o
.
f
,
error
:
o
.
f
o
.
spy
(
o
,
'
value
'
,{
_id
:
'
file.doc
'
,
_rev
:
o
.
rev
.
third
,
content
:
'
content3
'
},
'
loading "file.doc" -> conflict!
'
);
o
.
jio
.
get
(
'
file.doc
'
,
function
(
err
,
val
)
{
var
k
;
if
(
val
)
{
for
(
k
in
{
'
_creation_date
'
:
0
,
'
_last_modified
'
:
0
})
{
if
(
val
[
k
])
{
delete
val
[
k
];
}
else
{
val
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
if
(
!
o
.
conflict_obje
ct
)
{
return
ok
(
false
,
'
Cannot to continue the tests
'
);
}
o
.
tick
(
o
);
if
(
!
o
.
solveConfli
ct
)
{
return
ok
(
false
,
'
Cannot to continue the tests
'
);
}
// solving conflict
o
.
spy
(
'
status
'
,
'
done
'
,
'
solve conflict "file.doc".
'
);
o
.
conflict_object
.
solveConflict
(
'
content4
'
,{
error
:
o
.
f
,
success
:
function
(
r
)
{
o
.
f
(
r
)
;
o
.
rev
.
forth
=
r
.
revision
;
o
.
spy
(
o
,
'
value
'
,{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
'
3
'
},
'
solve conflict "file.doc".
'
);
o
.
solveConflict
(
'
content4
'
,
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev
.
forth
=
val
.
rev
;
val
.
rev
=
val
.
rev
?
val
.
rev
.
split
(
'
-
'
)[
0
]:
undefined
;
}
o
.
f
(
err
,
val
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
forth
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
second
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
third
);
...
...
@@ -1540,33 +1691,9 @@ test ('Revision Conflict', function() {
test
(
'
Conflict in a conflict solving
'
,
function
()
{
var
o
=
{};
o
.
clock
=
this
.
sandbox
.
useFakeTimers
();
o
.
t
=
this
;
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
function
(
res
,
value
,
message
,
function_name
)
{
function_name
=
function_name
||
'
f
'
;
o
[
function_name
]
=
function
(
result
)
{
if
(
res
===
'
status
'
)
{
if
(
result
&&
result
.
conflict_object
)
{
result
=
'
conflict
'
;
}
else
if
(
result
&&
typeof
result
.
status
!==
'
undefined
'
)
{
result
=
'
fail
'
;
}
else
{
result
=
'
done
'
;
}
}
deepEqual
(
result
,
value
,
message
);
};
o
.
t
.
spy
(
o
,
function_name
);
};
o
.
tick
=
function
(
tick
,
function_name
)
{
function_name
=
function_name
||
'
f
'
o
.
clock
.
tick
(
tick
||
1000
);
if
(
!
o
[
function_name
].
calledOnce
)
{
if
(
o
[
function_name
].
called
)
{
ok
(
false
,
'
too much results
'
);
}
else
{
ok
(
false
,
'
no response
'
);
}
}
};
o
.
spy
=
basic_spy_function
;
o
.
tick
=
basic_tick_function
;
o
.
localNamespace
=
'
jio/local/conflictconflict/jiotests/
'
;
o
.
rev
=
{};
o
.
checkContent
=
function
(
string
,
message
)
{
...
...
@@ -1584,73 +1711,165 @@ test ('Conflict in a conflict solving', function () {
o
.
jio
=
JIO
.
newJio
({
type
:
'
conflictmanager
'
,
storage
:
o
.
secondstorage_spec
});
// create a new file
o
.
spy
(
'
status
'
,
'
done
'
,
'
new file "file.doc", revision: "0".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content1
'
,{
previous_revision
:
'
0
'
,
error
:
o
.
f
,
success
:
function
(
value
){
o
.
rev
.
first
=
value
.
revision
;
o
.
f
(
value
);
}
o
.
test_message
=
'
new file "file.doc", revision: "0".
'
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content1
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
o
.
f
();
if
(
val
)
{
o
.
rev
.
first
=
val
.
rev
;
val
.
rev
=
checkRev
(
val
.
rev
);
}
deepEqual
(
err
||
val
,{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
o
.
rev
.
first
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
o
.
rev
.
first
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
// modify the file from the second revision instead of the third
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
modify "file.doc", revision: "0" -> conflict!
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content2
'
,{
previous_revision
:
"
0
"
,
success
:
o
.
f
,
error
:
function
(
error
)
{
o
.
f
(
error
);
o
.
conflict_object
=
error
.
conflict_object
;
o
.
rev
.
second
=
o
.
conflict_object
?
o
.
conflict_object
.
revision
:
'
?
'
;
}
o
.
test_message
=
'
modify "file.doc", revision: "0" -> conflict!
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content2
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
o
.
f
();
var
k
;
if
(
err
)
{
o
.
rev
.
second
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
second
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
first
,
o
.
rev
.
second
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
second
)]},
revs_info
:[{
rev
:
o
.
rev
.
first
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
second
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
second
);
if
(
!
o
.
conflict_obje
ct
)
{
return
ok
(
false
,
'
Cannot to continue the tests
'
);
}
if
(
!
o
.
solveConfli
ct
)
{
return
ok
(
false
,
'
Cannot to continue the tests
'
);
}
// saving another time
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
modify "file.doc" when solving, revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content3
'
,{
previous_revision
:
o
.
rev
.
first
,
error
:
function
(
e
){
o
.
f
(
e
);
o
.
rev
.
third
=
o
.
conflict_object
?
o
.
conflict_object
.
revision
:
'
?
'
;
},
success
:
o
.
f
o
.
test_message
=
'
modify "file.doc" when solving, revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content3
'
,
_rev
:
o
.
rev
.
first
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
){
o
.
f
();
if
(
err
)
{
o
.
rev
.
third
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
third
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
second
,
o
.
rev
.
third
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
2
,
ids
:[
getHashFromRev
(
o
.
rev
.
third
),
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
o
.
rev
.
second
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
third
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
third
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
// solving first conflict
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
solving conflict "file.doc" -> conflict!
'
);
o
.
conflict_object
.
solveConflict
(
'
content4
'
,{
success
:
o
.
f
,
error
:
function
(
error
)
{
o
.
rev
.
forth
=
'
?
'
;
if
(
error
.
conflict_object
)
{
o
.
conflict_object
=
error
.
conflict_object
;
o
.
rev
.
forth
=
o
.
conflict_object
.
revision
;
}
o
.
f
(
error
);
}
})
o
.
tick
();
o
.
test_message
=
'
solving conflict "file.doc" -> conflict!
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
solveConflict
(
'
content4
'
,{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
o
.
f
();
if
(
err
)
{
o
.
rev
.
forth
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
forth
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
third
,
o
.
rev
.
forth
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
2
,
ids
:[
getHashFromRev
(
o
.
rev
.
forth
),
getHashFromRev
(
o
.
rev
.
second
)]},
revs_info
:[{
rev
:
o
.
rev
.
third
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
forth
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
forth
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
second
);
if
(
!
o
.
solveConflict
)
{
return
ok
(
false
,
'
Cannot to continue the tests
'
);
}
// solving last conflict
o
.
spy
(
'
status
'
,
'
done
'
,
'
solving last conflict "file.doc".
'
);
o
.
conflict_object
.
solveConflict
(
'
content5
'
,{
error
:
o
.
f
,
success
:
function
(
v
)
{
o
.
f
(
v
);
o
.
rev
.
fith
=
v
.
revision
;
}
o
.
test_message
=
'
solving last conflict "file.doc".
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
solveConflict
(
'
content5
'
,{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
if
(
val
)
{
o
.
rev
.
fith
=
val
.
rev
;
val
.
rev
=
checkRev
(
val
.
rev
);
}
deepEqual
(
err
||
val
,{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
o
.
rev
.
fith
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
3
,
ids
:[
getHashFromRev
(
o
.
rev
.
fith
),
getHashFromRev
(
o
.
rev
.
forth
),
getHashFromRev
(
o
.
rev
.
second
)]},
revs_info
:[{
rev
:
o
.
rev
.
fith
,
status
:
'
available
'
}]
},
o
.
test_message
);
o
.
f
();
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
fith
);
o
.
jio
.
stop
();
...
...
@@ -1659,33 +1878,9 @@ test ('Conflict in a conflict solving', function () {
test
(
'
Remove revision conflict
'
,
function
()
{
var
o
=
{};
o
.
clock
=
this
.
sandbox
.
useFakeTimers
();
o
.
t
=
this
;
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
function
(
res
,
value
,
message
,
function_name
)
{
function_name
=
function_name
||
'
f
'
;
o
[
function_name
]
=
function
(
result
)
{
if
(
res
===
'
status
'
)
{
if
(
result
&&
result
.
conflict_object
)
{
result
=
'
conflict
'
;
}
else
if
(
result
&&
typeof
result
.
status
!==
'
undefined
'
)
{
result
=
'
fail
'
;
}
else
{
result
=
'
done
'
;
}
}
deepEqual
(
result
,
value
,
message
);
};
o
.
t
.
spy
(
o
,
function_name
);
};
o
.
tick
=
function
(
tick
,
function_name
)
{
function_name
=
function_name
||
'
f
'
o
.
clock
.
tick
(
tick
||
1000
);
if
(
!
o
[
function_name
].
calledOnce
)
{
if
(
o
[
function_name
].
called
)
{
ok
(
false
,
'
too much results
'
);
}
else
{
ok
(
false
,
'
no response
'
);
}
}
};
o
.
spy
=
basic_spy_function
;
o
.
tick
=
basic_tick_function
;
o
.
localNamespace
=
'
jio/local/removeconflict/jiotests/
'
;
o
.
rev
=
{};
o
.
checkContent
=
function
(
string
,
message
)
{
...
...
@@ -1703,77 +1898,189 @@ test ('Remove revision conflict', function () {
o
.
jio
=
JIO
.
newJio
({
type
:
'
conflictmanager
'
,
storage
:
o
.
secondstorage_spec
});
o
.
spy
(
'
status
'
,
'
done
'
,
'
new file "file.doc", revision: "0".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content1
'
,{
previous_revision
:
'
0
'
,
error
:
o
.
f
,
success
:
function
(
value
){
o
.
rev
.
first
=
value
.
revision
;
o
.
f
(
value
);
}
o
.
test_message
=
'
new file "file.doc", revision: "0".
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content1
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
o
.
f
();
if
(
val
)
{
o
.
rev
.
first
=
val
.
rev
;
val
.
rev
=
checkRev
(
val
.
rev
);
}
deepEqual
(
err
||
val
,{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
o
.
rev
.
first
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
o
.
rev
.
first
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
o
.
spy
(
'
status
'
,
'
fail
'
,
'
remove "file.doc", revision: "wrong" -> conflict!
'
);
o
.
jio
.
removeDocument
(
'
file.doc
'
,{
previous_revision
:
'
wrong
'
,
success
:
o
.
f
,
error
:
function
(
e
)
{
o
.
f
(
e
);
}
o
.
test_message
=
'
remove "file.doc", revision: "wrong" -> conflict!
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
remove
(
{
_id
:
'
file.doc
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
,
rev
:
'
wrong
'
},
function
(
err
,
val
)
{
o
.
f
();
if
(
err
)
{
o
.
rev
.
second
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
second
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
first
,
o
.
rev
.
second
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
second
)]},
revs_info
:[{
rev
:
o
.
rev
.
first
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
second
,
status
:
'
deleted
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
new file again "file.doc", revision: "0".
'
);
o
.
jio
.
saveDocument
(
'
file.doc
'
,
'
content2
'
,{
previous_revision
:
'
0
'
,
success
:
o
.
f
,
error
:
function
(
error
)
{
o
.
f
(
error
);
o
.
rev
.
second
=
error
.
conflict_object
?
error
.
conflict_object
.
revision
:
'
?
'
;
}
o
.
test_message
=
'
new file again "file.doc".
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
put
(
{
_id
:
'
file.doc
'
,
content
:
'
content2
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
)
{
o
.
f
();
if
(
err
)
{
o
.
rev
.
third
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
third
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
first
,
o
.
rev
.
second
,
o
.
rev
.
third
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
1
,
ids
:[
getHashFromRev
(
o
.
rev
.
third
)]},
revs_info
:[{
rev
:
o
.
rev
.
first
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
second
,
status
:
'
deleted
'
},
{
rev
:
o
.
rev
.
third
,
status
:
'
available
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
secon
d
);
o
.
tick
(
o
);
o
.
checkContent
(
'
file.doc.
'
+
o
.
rev
.
thir
d
);
o
.
spy
(
'
status
'
,
'
conflict
'
,
'
remove "file.doc", revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
);
o
.
jio
.
removeDocument
(
'
file.doc
'
,{
revision
:
o
.
rev
.
first
,
success
:
o
.
f
,
error
:
function
(
error
)
{
o
.
conflict_object
=
error
.
conflict_object
;
o
.
f
(
error
);
o
.
rev
.
third
=
o
.
conflict_object
?
o
.
conflict_object
.
revision
:
'
?
'
;
}
o
.
test_message
=
'
remove "file.doc", revision: "
'
+
o
.
rev
.
first
+
'
" -> conflict!
'
o
.
f
=
o
.
t
.
spy
();
o
.
jio
.
remove
(
{
_id
:
'
file.doc
'
},
{
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
,
rev
:
o
.
rev
.
first
},
function
(
err
,
val
)
{
o
.
f
();
if
(
err
)
{
o
.
rev
.
forth
=
err
.
rev
;
err
.
rev
=
checkRev
(
err
.
rev
);
if
(
err
.
conflicts
&&
err
.
conflicts
.
rows
)
{
o
.
solveConflict
=
checkConflictRow
(
err
.
conflicts
.
rows
[
0
]);
}
for
(
k
in
{
'
error
'
:
0
,
'
message
'
:
0
,
'
reason
'
:
0
,
'
statusText
'
:
0
})
{
if
(
err
[
k
])
{
delete
err
[
k
];
}
else
{
err
[
k
]
=
'
ERROR:
'
+
k
+
'
is missing !
'
;
}
}
}
deepEqual
(
err
||
val
,{
rev
:
o
.
rev
.
forth
,
conflicts
:{
total_rows
:
1
,
rows
:[
{
id
:
'
file.doc
'
,
key
:[
o
.
rev
.
second
,
o
.
rev
.
third
,
o
.
rev
.
forth
],
value
:{
_solveConflict
:
'
function
'
}}]},
status
:
409
,
// just one revision in the history, it does not keep older
// revisions because it is not a revision manager storage.
revisions
:{
start
:
2
,
ids
:[
getHashFromRev
(
o
.
rev
.
forth
),
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
o
.
rev
.
second
,
status
:
'
deleted
'
},
{
rev
:
o
.
rev
.
third
,
status
:
'
available
'
},
{
rev
:
o
.
rev
.
forth
,
status
:
'
deleted
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
first
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
third
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
forth
);
if
(
!
o
.
conflict_object
)
{
return
ok
(
false
,
'
Cannot continue the tests
'
);
}
o
.
spy
(
'
status
'
,
'
done
'
,
'
solve "file.doc"
'
);
o
.
conflict_object
.
solveConflict
({
error
:
o
.
f
,
success
:
function
(
v
)
{
o
.
f
(
v
);
o
.
rev
.
forth
=
v
.
revision
;
}
if
(
!
o
.
solveConflict
)
{
return
ok
(
false
,
'
Cannot continue the tests
'
);
}
o
.
test_message
=
'
solve "file.doc"
'
;
o
.
f
=
o
.
t
.
spy
();
o
.
solveConflict
({
conflicts
:
true
,
revs
:
true
,
revs_info
:
true
},
function
(
err
,
val
){
o
.
f
();
if
(
val
)
{
o
.
rev
.
fith
=
val
.
rev
;
val
.
rev
=
checkRev
(
val
.
rev
);
}
deepEqual
(
err
||
val
,{
ok
:
true
,
id
:
'
file.doc
'
,
rev
:
o
.
rev
.
fith
,
conflicts
:{
total_rows
:
0
,
rows
:[]},
revisions
:{
start
:
3
,
ids
:[
getHashFromRev
(
o
.
rev
.
fith
),
getHashFromRev
(
o
.
rev
.
forth
),
getHashFromRev
(
o
.
rev
.
first
)]},
revs_info
:[{
rev
:
o
.
rev
.
fith
,
status
:
'
deleted
'
}]
},
o
.
test_message
);
});
o
.
tick
();
o
.
tick
(
o
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
second
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
third
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
forth
);
o
.
checkNoContent
(
'
file.doc.
'
+
o
.
rev
.
fith
);
o
.
jio
.
stop
();
});
test
(
'
Load Revisions
'
,
function
()
{
var
o
=
{};
o
.
clock
=
this
.
sandbox
.
useFakeTimers
();
o
.
t
=
this
;
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
basic_spy_function
;
o
.
tick
=
basic_tick_function
;
o
.
secondstorage_spec
=
{
type
:
'
local
'
,
username
:
'
loadrevisions
'
,
applicationname
:
'
jiotests
'
}
//////////////////////////////////////////////////////////////////////
o
.
jio
=
JIO
.
newJio
({
type
:
'
conflictmanager
'
,
storage
:
o
.
secondstorage_spec
});
o
.
spy
(
o
,
'
status
'
,
404
,
'
load file rev:1,
'
,
'
f
'
);
// 12 === Replaced
o
.
spy
(
o
,
'
status
'
,
404
,
'
load file rev:2
'
,
'
g
'
);
o
.
spy
(
o
,
'
status
'
,
404
,
'
and load file rev:3 at the same time
'
,
'
h
'
);
o
.
jio
.
get
(
'
file
'
,{
rev
:
'
1
'
},
o
.
f
);
o
.
jio
.
get
(
'
file
'
,{
rev
:
'
2
'
},
o
.
g
);
o
.
jio
.
get
(
'
file
'
,{
rev
:
'
3
'
},
o
.
h
);
o
.
tick
(
o
,
1000
,
'
f
'
);
o
.
tick
(
o
,
0
,
'
g
'
);
o
.
tick
(
o
,
0
,
'
h
'
);
o
.
jio
.
stop
();
});
};
// end thisfun
if
(
window
.
requirejs
)
{
...
...
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