Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Y
yjs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
sweng-group-15
yjs
Commits
08d07796
Commit
08d07796
authored
9 years ago
by
Kevin Jahns
Browse files
Options
Downloads
Patches
Plain Diff
added spec helper
parent
010d0d68
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/SpecHelper.js
+291
-0
291 additions, 0 deletions
src/SpecHelper.js
with
291 additions
and
0 deletions
src/SpecHelper.js
0 → 100644
+
291
−
0
View file @
08d07796
/* eslint-env browser, jasmine */
/*
This is just a compilation of functions that help to test this library!
*/
// When testing, you store everything on the global object. We call it g
var
Y
=
require
(
'
./y.js
'
)
module
.
exports
=
Y
var
g
if
(
typeof
global
!==
'
undefined
'
)
{
g
=
global
}
else
if
(
typeof
window
!==
'
undefined
'
)
{
g
=
window
}
else
{
throw
new
Error
(
'
No global object?
'
)
}
g
.
g
=
g
g
.
YConcurrency_TestingMode
=
true
jasmine
.
DEFAULT_TIMEOUT_INTERVAL
=
20000
g
.
describeManyTimes
=
function
describeManyTimes
(
times
,
name
,
f
)
{
for
(
var
i
=
0
;
i
<
times
;
i
++
)
{
describe
(
name
,
f
)
}
}
/*
Wait for a specified amount of time (in ms). defaults to 5ms
*/
function
wait
(
t
)
{
if
(
t
==
null
)
{
t
=
5
}
return
new
Promise
(
function
(
resolve
)
{
setTimeout
(
function
()
{
resolve
()
},
t
*
3
)
})
}
g
.
wait
=
wait
g
.
databases
=
[
'
Memory
'
]
if
(
typeof
window
!==
'
undefined
'
)
{
g
.
databases
.
push
(
'
IndexedDB
'
)
}
/*
returns a random element of o.
works on Object, and Array
*/
function
getRandom
(
o
)
{
if
(
o
instanceof
Array
)
{
return
o
[
Math
.
floor
(
Math
.
random
()
*
o
.
length
)]
}
else
if
(
o
.
constructor
===
Object
)
{
var
ks
=
[]
for
(
var
key
in
o
)
{
ks
.
push
(
key
)
}
return
o
[
getRandom
(
ks
)]
}
}
g
.
getRandom
=
getRandom
function
getRandomNumber
(
n
)
{
if
(
n
==
null
)
{
n
=
9999
}
return
Math
.
floor
(
Math
.
random
()
*
n
)
}
g
.
getRandomNumber
=
getRandomNumber
function
*
applyTransactions
(
relAmount
,
numberOfTransactions
,
objects
,
users
,
transactions
)
{
function
randomTransaction
(
root
)
{
var
f
=
getRandom
(
transactions
)
f
(
root
)
}
for
(
var
i
=
0
;
i
<
numberOfTransactions
*
relAmount
+
1
;
i
++
)
{
var
r
=
Math
.
random
()
if
(
r
>=
0.5
)
{
// 50% chance to flush
users
[
0
].
connector
.
flushOne
()
// flushes for some user.. (not necessarily 0)
}
else
if
(
r
>=
0.05
)
{
// 45% chance to create operation
randomTransaction
(
getRandom
(
objects
))
}
else
{
// 5% chance to disconnect/reconnect
var
u
=
getRandom
(
users
)
if
(
u
.
connector
.
isDisconnected
())
{
yield
u
.
reconnect
()
}
else
{
yield
u
.
disconnect
()
}
}
yield
wait
()
}
}
g
.
applyRandomTransactionsAllRejoinNoGC
=
async
(
function
*
applyRandomTransactions
(
users
,
objects
,
transactions
,
numberOfTransactions
)
{
yield
*
applyTransactions
(
1
,
numberOfTransactions
,
objects
,
users
,
transactions
)
yield
users
[
0
].
connector
.
flushAll
()
yield
wait
()
for
(
var
u
in
users
)
{
yield
users
[
u
].
reconnect
()
}
yield
wait
(
100
)
yield
users
[
0
].
connector
.
flushAll
()
yield
g
.
garbageCollectAllUsers
(
users
)
})
g
.
applyRandomTransactionsWithGC
=
async
(
function
*
applyRandomTransactions
(
users
,
objects
,
transactions
,
numberOfTransactions
)
{
yield
*
applyTransactions
(
1
,
numberOfTransactions
,
objects
,
users
.
slice
(
1
),
transactions
)
yield
users
[
0
].
connector
.
flushAll
()
yield
g
.
garbageCollectAllUsers
(
users
)
yield
wait
(
100
)
for
(
var
u
in
users
)
{
// TODO: here, we enforce that two users never sync at the same time with u[0]
// enforce that in the connector itself!
yield
users
[
u
].
reconnect
()
}
yield
wait
(
100
)
yield
users
[
0
].
connector
.
flushAll
()
yield
wait
(
100
)
yield
g
.
garbageCollectAllUsers
(
users
)
})
g
.
garbageCollectAllUsers
=
async
(
function
*
garbageCollectAllUsers
(
users
)
{
// gc two times because of the two gc phases (really collect everything)
yield
wait
(
100
)
for
(
var
i
in
users
)
{
yield
users
[
i
].
db
.
garbageCollect
()
yield
users
[
i
].
db
.
garbageCollect
()
}
yield
wait
(
100
)
})
g
.
compareAllUsers
=
async
(
function
*
compareAllUsers
(
users
)
{
var
s1
,
s2
// state sets
var
ds1
,
ds2
// delete sets
var
allDels1
,
allDels2
// all deletions
var
db1
=
[]
// operation store of user1
// t1 and t2 basically do the same. They define t[1,2], ds[1,2], and allDels[1,2]
function
*
t1
()
{
s1
=
yield
*
this
.
getStateSet
()
ds1
=
yield
*
this
.
getDeleteSet
()
allDels1
=
[]
yield
*
this
.
ds
.
iterate
(
this
,
null
,
null
,
function
*
(
d
)
{
allDels1
.
push
(
d
)
})
}
function
*
t2
()
{
s2
=
yield
*
this
.
getStateSet
()
ds2
=
yield
*
this
.
getDeleteSet
()
allDels2
=
[]
yield
*
this
.
ds
.
iterate
(
this
,
null
,
null
,
function
*
(
d
)
{
allDels2
.
push
(
d
)
})
}
yield
users
[
0
].
connector
.
flushAll
()
yield
wait
()
yield
g
.
garbageCollectAllUsers
(
users
)
for
(
var
uid
=
0
;
uid
<
users
.
length
;
uid
++
)
{
var
u
=
users
[
uid
]
u
.
db
.
requestTransaction
(
function
*
()
{
// compare deleted ops against deleteStore
yield
*
this
.
os
.
iterate
(
this
,
null
,
null
,
function
*
(
o
)
{
if
(
o
.
deleted
===
true
)
{
expect
(
yield
*
this
.
isDeleted
(
o
.
id
)).
toBeTruthy
()
}
})
// compare deleteStore against deleted ops
var
ds
=
[]
yield
*
this
.
ds
.
iterate
(
this
,
null
,
null
,
function
*
(
d
)
{
ds
.
push
(
d
)
})
for
(
var
j
in
ds
)
{
var
d
=
ds
[
j
]
for
(
var
i
=
0
;
i
<
d
.
len
;
i
++
)
{
var
o
=
yield
*
this
.
getOperation
([
d
.
id
[
0
],
d
.
id
[
1
]
+
i
])
// gc'd or deleted
if
(
d
.
gc
)
{
expect
(
o
).
toBeFalsy
()
}
else
{
expect
(
o
.
deleted
).
toBeTruthy
()
}
}
}
})
// compare allDels tree
yield
wait
()
if
(
s1
==
null
)
{
u
.
db
.
requestTransaction
(
function
*
()
{
yield
*
t1
.
call
(
this
)
yield
*
this
.
os
.
iterate
(
this
,
null
,
null
,
function
*
(
o
)
{
o
=
Y
.
utils
.
copyObject
(
o
)
delete
o
.
origin
db1
.
push
(
o
)
})
})
yield
wait
()
}
else
{
// TODO: make requestTransaction return a promise..
u
.
db
.
requestTransaction
(
function
*
()
{
yield
*
t2
.
call
(
this
)
expect
(
s1
).
toEqual
(
s2
)
expect
(
allDels1
).
toEqual
(
allDels2
)
// inner structure
expect
(
ds1
).
toEqual
(
ds2
)
// exported structure
var
count
=
0
yield
*
this
.
os
.
iterate
(
this
,
null
,
null
,
function
*
(
o
)
{
o
=
Y
.
utils
.
copyObject
(
o
)
delete
o
.
origin
expect
(
db1
[
count
++
]).
toEqual
(
o
)
})
})
yield
wait
()
}
}
})
g
.
createUsers
=
async
(
function
*
createUsers
(
self
,
numberOfUsers
,
database
)
{
if
(
Y
.
utils
.
globalRoom
.
users
[
0
]
!=
null
)
{
yield
Y
.
utils
.
globalRoom
.
users
[
0
].
flushAll
()
}
// destroy old users
for
(
var
u
in
Y
.
utils
.
globalRoom
.
users
)
{
Y
.
utils
.
globalRoom
.
users
[
u
].
y
.
destroy
()
}
self
.
users
=
null
var
promises
=
[]
for
(
var
i
=
0
;
i
<
numberOfUsers
;
i
++
)
{
promises
.
push
(
Y
({
db
:
{
name
:
database
,
namespace
:
'
User
'
+
i
,
cleanStart
:
true
,
gcTimeout
:
-
1
},
connector
:
{
name
:
'
Test
'
,
debug
:
false
}
}))
}
self
.
users
=
yield
Promise
.
all
(
promises
)
return
self
.
users
})
/*
Until async/await arrives in js, we use this function to wait for promises
by yielding them.
*/
function
async
(
makeGenerator
)
{
return
function
(
arg
)
{
var
generator
=
makeGenerator
.
apply
(
this
,
arguments
)
function
handle
(
result
)
{
if
(
result
.
done
)
return
Promise
.
resolve
(
result
.
value
)
return
Promise
.
resolve
(
result
.
value
).
then
(
function
(
res
)
{
return
handle
(
generator
.
next
(
res
))
},
function
(
err
)
{
return
handle
(
generator
.
throw
(
err
))
})
}
try
{
return
handle
(
generator
.
next
())
}
catch
(
ex
)
{
generator
.
throw
(
ex
)
// return Promise.reject(ex)
}
}
}
g
.
async
=
async
function
logUsers
(
self
)
{
if
(
self
.
constructor
===
Array
)
{
self
=
{
users
:
self
}
}
self
.
users
[
0
].
db
.
logTable
()
self
.
users
[
1
].
db
.
logTable
()
self
.
users
[
2
].
db
.
logTable
()
}
g
.
logUsers
=
logUsers
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment