@@ -100,109 +100,108 @@ adapters.forEach(function (adapters) {
100100 } ) ;
101101 } ) ;
102102
103- it ( '#3179 conflicts synced, live sync' , function ( ) {
104- var local = new PouchDB ( dbs . name ) ;
105- var remote = new PouchDB ( dbs . remote ) ;
106- var sync = local . sync ( remote , { live : true } ) ;
107- function waitForUptodate ( ) {
103+ it ( '#3179 conflicts synced, live sync' , async function ( ) {
104+ const local = new PouchDB ( dbs . name ) ;
105+ const remote = new PouchDB ( dbs . remote ) ;
106+ const sync1 = local . sync ( remote , { live : true } ) ;
108107
109- function defaultToEmpty ( promise ) {
110- return promise . catch ( function ( err ) {
111- if ( err . status !== 404 ) {
112- throw err ;
113- }
114- return { _revisions : [ ] } ;
115- } ) ;
116- }
108+ function defaultToEmpty ( promise ) {
109+ return promise . catch ( function ( err ) {
110+ if ( err . status !== 404 ) {
111+ throw err ;
112+ }
113+ return { _revisions : [ ] } ;
114+ } ) ;
115+ }
117116
118- return defaultToEmpty ( local . get ( '1' , {
119- revs : true ,
120- conflicts : true
121- } ) ) . then ( function ( localDoc ) {
122- return defaultToEmpty ( remote . get ( '1' , {
117+ async function waitForUptodate ( ) {
118+ for ( let limit = 0 ; limit < 10 ; ++ limit ) {
119+ if ( limit > 0 ) {
120+ // we can get caught in an infinite loop here when using adapters based
121+ // on microtasks, e.g. memdown, so use setTimeout() to get a macrotask
122+ await new Promise ( function ( resolve ) {
123+ setTimeout ( resolve , 100 ) ;
124+ } ) ;
125+ }
126+
127+ const localDoc = await defaultToEmpty ( local . get ( '1' , {
123128 revs : true ,
124129 conflicts : true
125- } ) ) . then ( function ( remoteDoc ) {
126- var revsEqual = JSON . stringify ( localDoc . _revisions ) ===
127- JSON . stringify ( remoteDoc . _revisions ) ;
128- var conflictsEqual = JSON . stringify ( localDoc . _conflicts || [ ] ) ===
129- JSON . stringify ( remoteDoc . _conflicts || [ ] ) ;
130- if ( ! revsEqual || ! conflictsEqual ) {
131- // we can get caught in an infinite loop here when using adapters based
132- // on microtasks, e.g. memdown, so use setTimeout() to get a macrotask
133- return new Promise ( function ( resolve ) {
134- setTimeout ( resolve , 0 ) ;
135- } ) . then ( waitForUptodate ) ;
136- }
137- } ) ;
138- } ) ;
130+ } ) ) ;
131+ const remoteDoc = await defaultToEmpty ( remote . get ( '1' , {
132+ revs : true ,
133+ conflicts : true
134+ } ) ) ;
135+ const revsEqual = JSON . stringify ( localDoc . _revisions ) ===
136+ JSON . stringify ( remoteDoc . _revisions ) ;
137+ const conflictsEqual = JSON . stringify ( localDoc . _conflicts || [ ] ) ===
138+ JSON . stringify ( remoteDoc . _conflicts || [ ] ) ;
139+
140+ if ( revsEqual && conflictsEqual ) {
141+ // Everything's fine, continue with the test.
142+ return ;
143+ }
144+ }
145+
146+ // Tried 10 times, throw an error to cancel the test.
147+ throw new Error ( "retry limit reached" ) ;
139148 }
140149
141- function waitForConflictsResolved ( ) {
142- return new Promise ( function ( resolve ) {
143- var changes = remote . changes ( {
144- live : true ,
145- include_docs : true ,
146- conflicts : true
147- } ) . on ( 'change' , function ( change ) {
148- if ( ! ( '_conflicts' in change . doc ) ) {
149- changes . cancel ( ) ;
150- }
151- } ) ;
152- changes . on ( 'complete' , resolve ) ;
150+ async function waitForConflictsResolved ( ) {
151+ const changes = remote . changes ( {
152+ live : true ,
153+ include_docs : true ,
154+ conflicts : true ,
153155 } ) ;
156+
157+ changes . on ( 'change' , function ( change ) {
158+ if ( ! ( '_conflicts' in change . doc ) ) {
159+ changes . cancel ( ) ;
160+ }
161+ } ) ;
162+
163+ return await changes ;
154164 }
155165
156- function cleanup ( ) {
166+ function cleanup ( sync ) {
157167 return new Promise ( function ( resolve , reject ) {
158168 sync . on ( 'complete' , resolve ) ;
159169 sync . on ( 'error' , reject ) ;
160170 sync . cancel ( ) ;
161- sync = null ;
162171 } ) ;
163172 }
164173
165- return local . put ( { _id : '1' } ) . then ( function ( ) {
166- return waitForUptodate ( ) ;
167- } ) . then ( function ( ) {
168- sync . cancel ( ) ;
169- return waitForUptodate ( ) ;
170- } ) . then ( function ( ) {
171- return local . get ( '1' ) . then ( function ( doc ) {
172- doc . foo = Math . random ( ) ;
173- return local . put ( doc ) ;
174- } ) ;
175- } ) . then ( function ( ) {
176- return remote . get ( '1' ) . then ( function ( doc ) {
177- doc . foo = Math . random ( ) ;
178- return remote . put ( doc ) ;
179- } ) ;
180- } ) . then ( function ( ) {
181- sync = local . sync ( remote , { live : true } ) ;
182- return waitForUptodate ( ) ;
183- } ) . then ( function ( ) {
184- return local . get ( '1' , { conflicts : true } ) . then ( function ( doc ) {
185- should . exist ( doc . _conflicts , 'conflicts expected, but none were found' ) ;
186- return local . remove ( doc . _id , doc . _conflicts [ 0 ] ) ;
187- } ) ;
188- } ) . then ( function ( ) {
189- return waitForConflictsResolved ( ) ;
190- } ) . then ( function ( ) {
191- return local . get ( '1' , { conflicts : true , revs : true } ) ;
192- } ) . then ( function ( localDoc ) {
193- return remote . get ( '1' , {
194- conflicts : true ,
195- revs : true
196- } ) . then ( function ( remoteDoc ) {
197- remoteDoc . should . deep . equal ( localDoc ) ;
198- } ) ;
199- } ) . then ( function ( ) {
200- return cleanup ( ) ;
201- } , function ( err ) {
202- return cleanup ( ) . then ( function ( ) {
203- throw err ;
204- } ) ;
174+ await local . put ( { _id : '1' } ) ;
175+ await waitForUptodate ( ) ;
176+ await cleanup ( sync1 ) ;
177+
178+ await waitForUptodate ( ) ;
179+ const doc1 = await local . get ( '1' ) ;
180+ const randomNumber = Math . random ( ) ;
181+ doc1 . foo = randomNumber ;
182+ await local . put ( doc1 ) ;
183+
184+ const doc2 = await remote . get ( '1' ) ;
185+ // set conflicting property `foo`
186+ doc2 . foo = randomNumber + 1 ;
187+ await remote . put ( doc2 ) ;
188+
189+ const sync2 = local . sync ( remote , { live : true } ) ;
190+ await waitForUptodate ( ) ;
191+
192+ const doc3 = await local . get ( '1' , { conflicts : true } ) ;
193+ should . exist ( doc3 . _conflicts , 'conflicts expected, but none were found' ) ;
194+ await local . remove ( doc3 . _id , doc3 . _conflicts [ 0 ] ) ;
195+ await waitForConflictsResolved ( ) ;
196+
197+ const localDoc = await local . get ( '1' , { conflicts : true , revs : true } ) ;
198+ const remoteDoc = await remote . get ( '1' , {
199+ conflicts : true ,
200+ revs : true
205201 } ) ;
202+
203+ remoteDoc . should . deep . equal ( localDoc ) ;
204+ await cleanup ( sync2 ) ;
206205 } ) ;
207206
208207 it ( '#3179 conflicts synced, live repl' , function ( ) {
0 commit comments