@@ -2,928 +2,1140 @@ module Test.Main where
3import Prelude
3import Prelude
5−import Control.Monad.Aff (Aff, launchAff, forkAff, delay)
5+import Data.Array (head, drop)
6−import Control.Monad.Aff.Console (log)
6+import Data.Date as Date
7−import Control.Monad.Aff.AVar (AVAR, makeVar', modifyVar, peekVar, killVar)
7+import Data.DateTime (DateTime(..), Time(..))
8−import Control.Monad.Eff (Eff)
9−import Control.Monad.Eff.Class (liftEff)
10−import Control.Monad.Eff.Exception (EXCEPTION)
11−import Data.Date as Date
12−import Data.DateTime as DateTime
8+import Data.DateTime.Instant (toDateTime)
13−import Data.DateTime (DateTime(..), Date(..), Time(..))
9+import Data.Either (Either(..))
14−import Data.Enum (toEnum)
10+import Data.Enum (toEnum)
15−import Data.Maybe (Maybe(..), isNothing)
11+import Data.Maybe (Maybe(..), isNothing, maybe)
16−import Data.Time.Duration (Milliseconds(..))
12+import Data.Time.Duration (Milliseconds(..))
17−import Test.Spec (describe, it)
13+import Data.Traversable (traverse)
18−import Test.Spec.Assertions (shouldEqual, fail)
14+import Data.Tuple (Tuple(..), uncurry)
19−import Test.Spec.Mocha (MOCHA, runMocha)
21−import Database.IndexedDB.Core
15+import Database.IndexedDB.Core (CursorDirection(..), Database, Index, ObjectStore, Transaction, TransactionMode(..))
16+import Database.IndexedDB.IDBCursor as IDBCursor
17+import Database.IndexedDB.IDBDatabase as IDBDatabase
18+import Database.IndexedDB.IDBFactory as IDBFactory
19+import Database.IndexedDB.IDBIndex as IDBIndex
22−import Database.IndexedDB.IDBKey
20+import Database.IndexedDB.IDBKey (Key, none, toKey)
23−import Database.IndexedDB.IDBDatabase as IDBDatabase
21+import Database.IndexedDB.IDBKeyRange as IDBKeyRange
24−import Database.IndexedDB.IDBFactory as IDBFactory
22+import Database.IndexedDB.IDBObjectStore as IDBObjectStore
25−import Database.IndexedDB.IDBObjectStore as IDBObjectStore
23+import Database.IndexedDB.IDBTransaction as IDBTransaction
26−import Database.IndexedDB.IDBKeyRange as IDBKeyRange
24+import Effect (Effect)
27−
25+import Effect.Aff (Aff, attempt, delay, forkAff, launchAff, launchAff_)
28−
26+import Effect.Aff.AVar (AVar)
29−tearDown :: forall eff. String -> Int -> Database -> Aff (idb :: INDEXED_DB, exception :: EXCEPTION | eff) Unit
27+import Effect.Aff.AVar as AVar
28+import Effect.Class (liftEffect)
29+import Effect.Console (log)
30+import Effect.Exception (name)
31+import Effect.Now (now)
32+import Test.Spec (describe, it)
33+import Test.Spec.Assertions (shouldEqual, fail)
34+import Test.Spec.Reporter (consoleReporter)
35+import Test.Spec.Runner (runSpec)
39+launchAff' :: forall a. Aff a -> Effect Unit
43+modifyAVar :: forall a. (a -> a) -> AVar a -> Aff Unit
50+ launchAff_ $ runSpec [ consoleReporter ] $ do
51+ describe "IDBFactory" do
30−tearDown name version db = do
53+ tearDown name version db = do
31− liftEff $ IDBDatabase.close db
54+ IDBDatabase.close db
32− version' <- IDBFactory.deleteDatabase name
55+ version' <- IDBFactory.deleteDatabase name
33− version' `shouldEqual` version
56+ liftEffect $ log $ show version'
34−
57+ version' `shouldEqual` version
35−-- main :: forall eff. Eff (mocha :: MOCHA, idb :: INDEXED_DB, exception :: EXCEPTION, avar :: AVAR | eff) Unit
58+
37− describe "IDBFactory" do
38− it "open default" do
59+ it "open default" do
39− let name = "db-default"
61+ name = "db-default"
40 version = 1
62 version = 1
41− db <- IDBFactory.open name Nothing
63+ db <- IDBFactory.open name Nothing
42− { onUpgradeNeeded : Nothing
64+ { onUpgradeNeeded: Nothing
43− , onBlocked : Nothing
65+ , onBlocked: Nothing
45− IDBDatabase.name db `shouldEqual` name
67+ IDBDatabase.name db `shouldEqual` name
46− tearDown name version db
68+ tearDown name version db
49− it "open specific version" do
70+ it "open specific version" do
50− let name = "db-specific"
72+ name = "db-specific"
51 version = 14
73 version = 14
52− db <- IDBFactory.open name (Just version)
74+ db <- IDBFactory.open name (Just version)
53− { onUpgradeNeeded : Nothing
75+ { onUpgradeNeeded: Nothing
54− , onBlocked : Nothing
76+ , onBlocked: Nothing
56− IDBDatabase.name db `shouldEqual` name
78+ IDBDatabase.name db `shouldEqual` name
57− tearDown name version db
79+ tearDown name version db
60− it "open specific version -> close -> open latest" do
81+ it "open specific version -> close -> open latest" do
61− let name = "db-latest"
83+ name = "db-latest"
62 version = 14
84 version = 14
63− db <- IDBFactory.open name (Just version)
85+ db01 <- IDBFactory.open name (Just version)
64− { onUpgradeNeeded : Nothing
86+ { onUpgradeNeeded: Nothing
65− , onBlocked : Nothing
87+ , onBlocked: Nothing
67− IDBDatabase.name db `shouldEqual` name
89+ IDBDatabase.name db01 `shouldEqual` name
68− liftEff $ IDBDatabase.close db
90+ IDBDatabase.close db01
69− db <- IDBFactory.open name Nothing
91+ db02 <- IDBFactory.open name Nothing
70− { onUpgradeNeeded : Nothing
92+ { onUpgradeNeeded: Nothing
71− , onBlocked : Nothing
93+ , onBlocked: Nothing
73− tearDown name version db
95+ tearDown name version db02
76− it "open + onUpgradeNeed" do
97+ it "open + onUpgradeNeed" do
77− let name = "db-upgrade-needed"
99+ name = "db-upgrade-needed"
78 version = 1
100 version = 1
79− callback var db = do
101+ callback (Tuple varName varVersion) db _ { oldVersion } = do
80− _ <- launchAff $ modifyVar (const $ IDBDatabase.name db) var
102+ _ <- launchAff $ modifyAVar (const $ IDBDatabase.name db) varName
103+ _ <- launchAff $ modifyAVar (const $ oldVersion) varVersion
81 pure unit
104 pure unit
82− var <- makeVar' "-"
105+ varName <- AVar.new "-"
106+ varVersion <- AVar.new (-1)
83− db <- IDBFactory.open name Nothing
107+ db <- IDBFactory.open name Nothing
84− { onUpgradeNeeded : Just (callback var)
108+ { onUpgradeNeeded: Just (callback (Tuple varName varVersion))
85− , onBlocked : Nothing
109+ , onBlocked: Nothing
87− name <- peekVar var
111+ name' <- AVar.read varName
112+ version' <- AVar.read varVersion
88− name `shouldEqual` name
113+ name' `shouldEqual` name
114+ version' `shouldEqual` 0
89− tearDown name version db
115+ tearDown name version db
92− it "open + onBlocked" do
117+ it "open + onBlocked" do
93− let name = "db-blocked"
119+ name = "db-blocked"
94 version = 14
120 version = 14
95 callback var = do
121 callback var = do
96− _ <- launchAff $ modifyVar (const $ "db-blocked") var
122+ _ <- launchAff $ modifyAVar (const $ "db-blocked") var
97 pure unit
123 pure unit
99− var <- makeVar' "-"
125+ var <- AVar.new "-"
100− db01 <- IDBFactory.open name Nothing
126+ db01 <- IDBFactory.open name Nothing
101− { onUpgradeNeeded : Nothing
127+ { onUpgradeNeeded: Nothing
102− , onBlocked : Nothing
128+ , onBlocked: Nothing
104− _ <- forkAff do
130+ _ <- forkAff do
105− delay (Milliseconds 100.0)
131+ delay (Milliseconds 100.0)
106− liftEff $ IDBDatabase.close db01
132+ IDBDatabase.close db01
108− db02 <- IDBFactory.open name (Just version)
134+ db02 <- IDBFactory.open name (Just version)
109− { onUpgradeNeeded : Nothing
135+ { onUpgradeNeeded: Nothing
110− , onBlocked : Just (callback var)
136+ , onBlocked: Just (callback var)
112− name <- peekVar var
138+ name' <- AVar.read var
113− name `shouldEqual` name
139+ name' `shouldEqual` name
114− tearDown name version db02
140+ tearDown name version db02
116− describe "IDBKeyRange" do
142+ describe "IDBKeyRange" do
117− it "only(int)" do
143+ it "only(int)" do
118− let key = 14
145+ key = 14
119 range = IDBKeyRange.only key
146 range = IDBKeyRange.only key
120− IDBKeyRange.includes range (toKey key) `shouldEqual` true
147+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
122− it "only(string)" do
149+ it "only(string)" do
123− let key = "patate"
151+ key = "patate"
124 range = IDBKeyRange.only key
152 range = IDBKeyRange.only key
125− IDBKeyRange.includes range (toKey key) `shouldEqual` true
153+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
127− it "only(float)" do
155+ it "only(float)" do
128− let key = 14.42
157+ key = 14.42
129 range = IDBKeyRange.only key
158 range = IDBKeyRange.only key
130− IDBKeyRange.includes range (toKey key) `shouldEqual` true
159+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
132− it "only(date)" do
161+ it "only(date)" do
133− let mkey = DateTime
163+ mkey = DateTime
134 <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
164 <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
135 <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
165 <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
137− case mkey of
167+ case mkey of
138− Nothing ->
168+ Nothing ->
139− fail "unable to create datetime"
169+ fail "unable to create datetime"
140− Just key -> do
170+ Just key -> do
141− let range = IDBKeyRange.only key
171+ let range = IDBKeyRange.only key
142− IDBKeyRange.includes range (toKey key) `shouldEqual` true
172+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
144− it "only([int])" do
174+ it "only([int])" do
145− let key = [14, 42]
176+ key = [ 14, 42 ]
146 range = IDBKeyRange.only key
177 range = IDBKeyRange.only key
147− IDBKeyRange.includes range (toKey key) `shouldEqual` true
178+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
149− it "only([string])" do
180+ it "only([string])" do
150− let key = ["patate", "autruche"]
182+ key = [ "patate", "autruche" ]
151 range = IDBKeyRange.only key
183 range = IDBKeyRange.only key
152− IDBKeyRange.includes range (toKey key) `shouldEqual` true
184+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
154− it "lowerBound(14, open)" do
186+ it "lowerBound(14, open)" do
155− let key = 14
188+ key = 14
156− open = true
189+ open = true
157 range = IDBKeyRange.lowerBound key open
190 range = IDBKeyRange.lowerBound key open
158− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
191+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
159− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
192+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
160− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
193+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
162− it "lowerBound(14, close)" do
195+ it "lowerBound(14, close)" do
163− let key = 14
197+ key = 14
164− open = false
198+ open = false
165 range = IDBKeyRange.lowerBound key open
199 range = IDBKeyRange.lowerBound key open
166− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
200+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
167− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
201+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
168− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
202+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
170− it "upperBound(14, open)" do
204+ it "upperBound(14, open)" do
171− let key = 14
206+ key = 14
172− open = true
207+ open = true
173 range = IDBKeyRange.upperBound key open
208 range = IDBKeyRange.upperBound key open
174− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
209+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
175− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
210+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
176− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
211+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
178− it "upperBound(14, close)" do
213+ it "upperBound(14, close)" do
179− let key = 14
215+ key = 14
180− open = false
216+ open = false
181 range = IDBKeyRange.upperBound key open
217 range = IDBKeyRange.upperBound key open
182− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
218+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
183− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
219+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
184− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
220+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
186− it "bound(42, 14, open, open) => Nothing" do
222+ it "bound(42, 14, open, open) => Nothing" do
187− let lower = 42
224+ lower = 42
188− upper = 14
225+ upper = 14
189 lowerOpen = true
226 lowerOpen = true
190 upperOpen = true
227 upperOpen = true
191− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
228+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
192− isNothing mrange `shouldEqual` true
229+ isNothing mrange `shouldEqual` true
194− it "bound(14, 42, open, open)" do
231+ it "bound(14, 42, open, open)" do
195− let lower = 14
233+ lower = 14
196− upper = 42
234+ upper = 42
197 lowerOpen = true
235 lowerOpen = true
198 upperOpen = true
236 upperOpen = true
199− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
237+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
200− case mrange of
238+ case mrange of
201− Nothing ->
239+ Nothing ->
202− fail "invalid range provided"
240+ fail "invalid range provided"
203− Just range -> do
241+ Just range -> do
204− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
242+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
205− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
243+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
206− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
244+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
207− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
245+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
208− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
246+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
209− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
247+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
211− it "bound(14, 42, open, close)" do
249+ it "bound(14, 42, open, close)" do
212− let lower = 14
251+ lower = 14
213− upper = 42
252+ upper = 42
214 lowerOpen = true
253 lowerOpen = true
215 upperOpen = false
254 upperOpen = false
216− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
255+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
217− case mrange of
256+ case mrange of
218− Nothing ->
257+ Nothing ->
219− fail "invalid range provided"
258+ fail "invalid range provided"
220− Just range -> do
259+ Just range -> do
221− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
260+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
222− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
261+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
223− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
262+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
224− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
263+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
225− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
264+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
226− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
265+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
228− it "bound(14, 42, close, open)" do
267+ it "bound(14, 42, close, open)" do
229− let lower = 14
269+ lower = 14
230− upper = 42
270+ upper = 42
231 lowerOpen = false
271 lowerOpen = false
232 upperOpen = true
272 upperOpen = true
233− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
273+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
234− case mrange of
274+ case mrange of
235− Nothing ->
275+ Nothing ->
236− fail "invalid range provided"
276+ fail "invalid range provided"
237− Just range -> do
277+ Just range -> do
238− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
278+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
239− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
279+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
240− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
280+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
241− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
281+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
242− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
282+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
243− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
283+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
245− it "bound(14, 42, close, close)" do
285+ it "bound(14, 42, close, close)" do
246− let lower = 14
287+ lower = 14
247− upper = 42
288+ upper = 42
248 lowerOpen = false
289 lowerOpen = false
249 upperOpen = false
290 upperOpen = false
250− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
291+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
251− case mrange of
292+ case mrange of
252− Nothing ->
293+ Nothing ->
253− fail "invalid range provided"
294+ fail "invalid range provided"
254− Just range -> do
295+ Just range -> do
255− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
296+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
256− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
297+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
257− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
298+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
258− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
299+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
259− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
300+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
260− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
301+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
262− it "can access attributes of a range" do
303+ it "can access attributes of a range" do
263− let range = IDBKeyRange.lowerBound 14 true
304+ let range = IDBKeyRange.lowerBound 14 false
264− IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
305+ IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
265− IDBKeyRange.upper range `shouldEqual` (Nothing :: Maybe Key)
306+ IDBKeyRange.upper range `shouldEqual` none
266− IDBKeyRange.lowerOpen range `shouldEqual` true
307+ IDBKeyRange.lowerOpen range `shouldEqual` false
267− -- NOTE Not true on Chrome 56.x => The default value for the flag is `true`
268− -- IDBKeyRange.upperOpen range `shouldEqual` false
308+ IDBKeyRange.upperOpen range `shouldEqual` true
270− describe "IDBDatabase" do
310+ describe "IDBDatabase" do
271− it "createObjectStore (keyPath: [], autoIncrement: true)" do
311+ let
272− let dbName = "db-create-store-01"
312+ tearDown db = do
276− autoIncrement = true
277− callback var db = do
278− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
279− _ <- launchAff $ IDBObjectStore.name store `shouldEqual` storeName
280− _ <- launchAff $ IDBObjectStore.keyPath store `shouldEqual` keyPath
281− _ <- launchAff $ IDBObjectStore.autoIncrement store `shouldEqual` autoIncrement
282− _ <- launchAff $ IDBObjectStore.indexNames store `shouldEqual` []
283− _ <- launchAff $ modifyVar (const true) var
286− var <- makeVar' false
287− db <- IDBFactory.open dbName Nothing
288− { onUpgradeNeeded : Just (callback var)
289− , onBlocked : Nothing
291− hasBeenCalled <- peekVar var
292− hasBeenCalled `shouldEqual` true
293− tearDown dbName dbVersion db
296− it "createObjectStore (keyPath: [\"field\"], autoIncrement: true)" do
297− let dbName = "db-create-store-02"
301− autoIncrement = true
302− callback var db = do
303− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
304− _ <- launchAff $ IDBObjectStore.name store `shouldEqual` storeName
305− _ <- launchAff $ IDBObjectStore.keyPath store `shouldEqual` keyPath
306− _ <- launchAff $ IDBObjectStore.autoIncrement store `shouldEqual` autoIncrement
307− _ <- launchAff $ IDBObjectStore.indexNames store `shouldEqual` []
308− _ <- launchAff $ modifyVar (const true) var
311− var <- makeVar' false
312− db <- IDBFactory.open dbName Nothing
313− { onUpgradeNeeded : Just (callback var)
314− , onBlocked : Nothing
316− hasBeenCalled <- peekVar var
317− hasBeenCalled `shouldEqual` true
318− tearDown dbName dbVersion db
321− it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
322− let dbName = "db-create-store-03"
325− keyPath = ["a", "b"]
326− autoIncrement = false
327− callback var db = do
328− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
329− _ <- launchAff $ IDBObjectStore.name store `shouldEqual` storeName
330− _ <- launchAff $ IDBObjectStore.keyPath store `shouldEqual` keyPath
331− _ <- launchAff $ IDBObjectStore.autoIncrement store `shouldEqual` autoIncrement
332− _ <- launchAff $ IDBObjectStore.indexNames store `shouldEqual` []
333− _ <- launchAff $ modifyVar (const true) var
336− var <- makeVar' false
337− db <- IDBFactory.open dbName Nothing
338− { onUpgradeNeeded : Just (callback var)
339− , onBlocked : Nothing
341− hasBeenCalled <- peekVar var
342− hasBeenCalled `shouldEqual` true
343− tearDown dbName dbVersion db
346− it "createObjectStore (keyPath: [\"field\"], autoIncrement: false)" do
347− let dbName = "db-create-store-04"
351− autoIncrement = false
352− callback var db = do
353− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
354− _ <- launchAff $ IDBObjectStore.name store `shouldEqual` storeName
355− _ <- launchAff $ IDBObjectStore.keyPath store `shouldEqual` keyPath
356− _ <- launchAff $ IDBObjectStore.autoIncrement store `shouldEqual` autoIncrement
357− _ <- launchAff $ IDBObjectStore.indexNames store `shouldEqual` []
358− _ <- launchAff $ modifyVar (const true) var
361− var <- makeVar' false
362− db <- IDBFactory.open dbName Nothing
363− { onUpgradeNeeded : Just (callback var)
364− , onBlocked : Nothing
366− hasBeenCalled <- peekVar var
367− hasBeenCalled `shouldEqual` true
368− tearDown dbName dbVersion db
371− it "deleteObjectStore" do
372− let dbName = "db-delete-store"
376− autoIncrement = true
378− _ <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
380− callback2 var db = do
381− _ <- IDBDatabase.deleteObjectStore db storeName
382− _ <- launchAff $ modifyVar (const true) var
385− var <- makeVar' false
386− db <- IDBFactory.open dbName Nothing
387− { onUpgradeNeeded : Just callback
388− , onBlocked : Nothing
390− liftEff $ IDBDatabase.close db
313+ IDBDatabase.close db
391− db <- IDBFactory.open dbName (Just dbVersion)
314+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
392− { onUpgradeNeeded : Just (callback2 var)
315+ pure unit
393− , onBlocked : Nothing
316+
394− }
317+ setup storeParams = do
395− hasBeenCalled <- peekVar var
318+ let
396− hasBeenCalled `shouldEqual` true
319+ onUpgradeNeeded var db _ _ = launchAff' do
397− tearDown dbName dbVersion db
399− describe "IDBObjectStore" do
400− it "add(\"patate\", Nothing )" do
401− let dbName = "db-add"
405− autoIncrement = true
408− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
320+ store <- IDBDatabase.createObjectStore db "store" storeParams
409− key <- launchAff $ ((unsafeFromKey >>> shouldEqual key)
321+ _ <- AVar.put { db, store } var
410− <$> IDBObjectStore.add store "patate" Nothing)
413− db <- IDBFactory.open dbName Nothing
414− { onUpgradeNeeded : Just callback
415− , onBlocked : Nothing
417− tearDown dbName dbVersion db
419− it "add(\"patate\", Just 14 )" do
420− let dbName = "db-add"
424− autoIncrement = true
427− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
428− key <- launchAff $ ((unsafeFromKey >>> shouldEqual key)
429− <$> IDBObjectStore.add store "patate" (Just $ toKey key))
432− db <- IDBFactory.open dbName Nothing
433− { onUpgradeNeeded : Just callback
434− , onBlocked : Nothing
436− tearDown dbName dbVersion db
438− it "add(\"patate\", Just \"key\" )" do
439− let dbName = "db-add"
443− autoIncrement = true
446− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
447− key <- launchAff $ ((unsafeFromKey >>> shouldEqual key)
448− <$> IDBObjectStore.add store "patate" (Just $ toKey key))
449− pure unit
322+ pure unit
451− db <- IDBFactory.open dbName Nothing
325+ _ <- IDBFactory.open "db" Nothing
452− { onUpgradeNeeded : Just callback
326+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
453− , onBlocked : Nothing
327+ , onBlocked: Nothing
455− tearDown dbName dbVersion db
457− it "add(\"patate\", Just <date> )" do
458− let dbName = "db-add"
462− autoIncrement = true
464− <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
465− <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
467− case mkey of
330+ AVar.take var
332+ it "createObjectStore (keyPath: [], autoIncrement: true)" do
333+ { db, store } <- setup { keyPath: [], autoIncrement: true }
334+ IDBObjectStore.name store `shouldEqual` "store"
335+ IDBObjectStore.keyPath store `shouldEqual` []
336+ IDBObjectStore.autoIncrement store `shouldEqual` true
337+ IDBObjectStore.indexNames store `shouldEqual` []
340+ it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
341+ { db, store } <- setup { keyPath: [ "patate" ], autoIncrement: true }
342+ IDBObjectStore.name store `shouldEqual` "store"
343+ IDBObjectStore.keyPath store `shouldEqual` [ "patate" ]
344+ IDBObjectStore.autoIncrement store `shouldEqual` true
345+ IDBObjectStore.indexNames store `shouldEqual` []
348+ it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
349+ { db, store } <- setup { keyPath: [ "patate", "autruche" ], autoIncrement: false }
350+ IDBObjectStore.name store `shouldEqual` "store"
351+ IDBObjectStore.keyPath store `shouldEqual` [ "patate", "autruche" ]
352+ IDBObjectStore.autoIncrement store `shouldEqual` false
353+ IDBObjectStore.indexNames store `shouldEqual` []
356+ it "deleteObjectStore" do
358+ onUpgradeNeeded var db _ _ = launchAff' do
359+ _ <- IDBDatabase.deleteObjectStore db "store"
363+ { db } <- setup IDBDatabase.defaultParameters
364+ IDBDatabase.close db
365+ db' <- IDBFactory.open "db" (Just 999)
366+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
468− Nothing ->
367+ , onBlocked: Nothing
469− fail "unable to create datetime"
368+ }
470− Just key -> do
369+ deleted <- AVar.take var
471− let callback db = do
370+ deleted `shouldEqual` true
472− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
371+ tearDown db'
473− key <- launchAff $ ((unsafeFromKey >>> shouldEqual key)
372+
474− <$> IDBObjectStore.add store "patate" (Just $ toKey key))
373+ describe "IDBObjectStore" do
476−
375+ tearDown db = do
376+ IDBDatabase.close db
377+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
380+ setup { storeParams, onUpgradeNeeded } = do
382+ onUpgradeNeeded' var db _ _ = launchAff' do
383+ store <- IDBDatabase.createObjectStore db "store" storeParams
384+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure store)
385+ AVar.put { db, store } var
477− db <- IDBFactory.open dbName Nothing
388+ _ <- IDBFactory.open "db" Nothing
478− { onUpgradeNeeded : Just callback
389+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
479− , onBlocked : Nothing
390+ , onBlocked: Nothing
481− tearDown dbName dbVersion db
483− it "add(\"patate\", Just [14, 42] )" do
484− let dbName = "db-add"
488− autoIncrement = true
491− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
492− key <- launchAff $ ((unsafeFromKey >>> shouldEqual key)
493− <$> IDBObjectStore.add store "patate" (Just $ toKey key))
496− db <- IDBFactory.open dbName Nothing
393+ AVar.take var
497− { onUpgradeNeeded : Just callback
394+
498− , onBlocked : Nothing
500− tearDown dbName dbVersion db
502− it "clear()" do
395+ it "add()" do
503− let dbName = "db-clear"
396+ date <- liftEffect $ toDateTime <$> now
504− dbVersion = 1
397+ { db } <- setup
507− autoIncrement = true
398+ { storeParams: { autoIncrement: true, keyPath: [] }
508− callback db = do
399+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
509− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
400+ -- no key
401+ key <- IDBObjectStore.add store "patate" none
402+ (toKey 1) `shouldEqual` key
405+ key' <- IDBObjectStore.add store "patate" (Just 14)
406+ (toKey 14) `shouldEqual` key'
409+ key'' <- IDBObjectStore.add store "patate" (Just 14.42)
410+ (toKey 14.42) `shouldEqual` key''
413+ key''' <- IDBObjectStore.add store "patate" (Just "key")
414+ (toKey "key") `shouldEqual` key'''
417+ key'''' <- IDBObjectStore.add store "patate" (Just date)
418+ (toKey date) `shouldEqual` key''''
421+ key''''' <- IDBObjectStore.add store "patate" (Just $ toKey [ 14, 42 ])
422+ (toKey [ 14, 42 ]) `shouldEqual` key'''''
428+ { storeParams: IDBDatabase.defaultParameters
510− _ <- launchAff $ do
429+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
511− _ <- IDBObjectStore.add store "patate" (Just $ toKey 14)
430+ key <- IDBObjectStore.add store "patate" (Just 14)
512 _ <- IDBObjectStore.clear store
431 _ <- IDBObjectStore.clear store
513− v <- IDBObjectStore.get store (IDBKeyRange.only 14)
432+ val <- IDBObjectStore.get store (IDBKeyRange.only key)
514− v `shouldEqual` (Nothing :: Maybe Int)
433+ val `shouldEqual` (Nothing :: Maybe String)
518− db <- IDBFactory.open dbName Nothing
519− { onUpgradeNeeded : Just callback
520− , onBlocked : Nothing
522− tearDown dbName dbVersion db
435+ tearDown db
524− it "count(Nothing) " do
437+ it "count()" do
525− let dbName = "db-count"
438+ { db } <- setup
526− dbVersion = 1
439+ { storeParams: IDBDatabase.defaultParameters
527− storeName = "store"
440+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
529− autoIncrement = true
531− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
533− _ <- IDBObjectStore.add store "patate" Nothing
441+ _ <- IDBObjectStore.add store "patate" (Just 14)
534− _ <- IDBObjectStore.add store 14 Nothing
442+ _ <- IDBObjectStore.add store "autruche" (Just 42)
535 n <- IDBObjectStore.count store Nothing
443 n <- IDBObjectStore.count store Nothing
536 n `shouldEqual` 2
444 n `shouldEqual` 2
539− db <- IDBFactory.open dbName Nothing
540− { onUpgradeNeeded : Just callback
541− , onBlocked : Nothing
543− tearDown dbName dbVersion db
446+ tearDown db
546− it "getKey() (fixed)" do
448+ it "getKey()" do
547− let dbName = "db-getKey"
449+ { db } <- setup
548− dbVersion = 1
450+ { storeParams: IDBDatabase.defaultParameters
552− autoIncrement = false
554− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
555− _ <- launchAff $ do
451+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
556− key' <- IDBObjectStore.add store { id: key, value: 14 } Nothing
452+ key <- IDBObjectStore.add store "patate" (Just 14)
557− (unsafeFromKey key') `shouldEqual` key
558− key' <- IDBObjectStore.getKey store (IDBKeyRange.only key)
559− (unsafeFromKey <$> key') `shouldEqual` (Just key)
562− db <- IDBFactory.open dbName Nothing
563− { onUpgradeNeeded : Just callback
564− , onBlocked : Nothing
566− tearDown dbName dbVersion db
568− it "getKey() (given)" do
569− let dbName = "db-getKey"
573− autoIncrement = true
575− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
577− key <- IDBObjectStore.add store "patate" Nothing
578− mkey <- IDBObjectStore.getKey store (IDBKeyRange.only key)
579− mkey `shouldEqual` Just key
582− db <- IDBFactory.open dbName Nothing
583− { onUpgradeNeeded : Just callback
584− , onBlocked : Nothing
586− tearDown dbName dbVersion db
588− it "getKey() unknown" do
589− let dbName = "db-getKey"
593− autoIncrement = true
595− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
597− key <- IDBObjectStore.add store "patate" Nothing
598 mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
453 mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
599− mkey `shouldEqual` Nothing
454+ mkey `shouldEqual` (Just key)
601−
456+ mkey' <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
602− db <- IDBFactory.open dbName Nothing
457+ mkey' `shouldEqual` none
603− { onUpgradeNeeded : Just callback
604− , onBlocked : Nothing
606− tearDown dbName dbVersion db
459+ tearDown db
608− it "getAllKeys(nothing, nothing)" do
461+ it "getAllKeys()" do
609− let dbName = "db-getAllKeys"
462+ { db } <- setup
610− dbVersion = 1
463+ { storeParams: IDBDatabase.defaultParameters
613− autoIncrement = true
615− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
616− _ <- launchAff $ do
464+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
617− k1 <- IDBObjectStore.add store "patate" Nothing
465+ key1 <- IDBObjectStore.add store "patate" (Just 14)
618− k2 <- IDBObjectStore.add store "autruche" Nothing
466+ key2 <- IDBObjectStore.add store "autruche" (Just 42)
467+ key3 <- IDBObjectStore.add store 14 (Just 1337)
619 keys <- IDBObjectStore.getAllKeys store Nothing Nothing
470 keys <- IDBObjectStore.getAllKeys store Nothing Nothing
620− keys `shouldEqual` [k1,k2]
471+ keys `shouldEqual` [ key1, key2, key3 ]
623− db <- IDBFactory.open dbName Nothing
474+ keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
624− { onUpgradeNeeded : Just callback
475+ keys' `shouldEqual` [ key2, key3 ]
625− , onBlocked : Nothing
476+
626− }
477+ -- upper bound
627− tearDown dbName dbVersion db
629− it "getAllKeys(lowerBound(1, true), nothing)" do
630− let dbName = "db-getAllKeys"
634− autoIncrement = true
636− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
638− k1 <- IDBObjectStore.add store "patate" Nothing
639− k2 <- IDBObjectStore.add store "autruche" Nothing
640− k3 <- IDBObjectStore.add store 14 Nothing
641− keys <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) Nothing
478+ keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
642− keys `shouldEqual` [k2, k3]
479+ keys'' `shouldEqual` [ key1, key2 ]
645− db <- IDBFactory.open dbName Nothing
482+ keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
646− { onUpgradeNeeded : Just callback
483+ keys''' `shouldEqual` [ key1, key2 ]
647− , onBlocked : Nothing
649− tearDown dbName dbVersion db
485+ tearDown db
651− it "openCursor(Nothing, Next)" do
487+ it "openCursor()" do
652− let dbName = "db-openCursor"
488+ let
653− dbVersion = 1
489+ cb =
654− storeName = "store"
490+ { onSuccess: const $ pure unit
655− keyPath = []
491+ , onError: show >>> fail >>> launchAff'
656− autoIncrement = true
492+ , onComplete: pure unit
657− callback db = do
493+ }
658− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
494+ { db } <- setup
495+ { storeParams: IDBDatabase.defaultParameters
659− _ <- launchAff $ do
496+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
660− _ <- IDBObjectStore.openCursor store Nothing Next
497+ _ <- IDBObjectStore.openCursor store Nothing Next cb
661− pure unit
498+ _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
664− db <- IDBFactory.open dbName Nothing
665− { onUpgradeNeeded : Just callback
666− , onBlocked : Nothing
668− tearDown dbName dbVersion db
670− it "openCursor(Nothing, NextUnique)" do
671− let dbName = "db-openCursor"
675− autoIncrement = true
677− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
679− _ <- IDBObjectStore.openCursor store Nothing NextUnique
683− db <- IDBFactory.open dbName Nothing
684− { onUpgradeNeeded : Just callback
685− , onBlocked : Nothing
687− tearDown dbName dbVersion db
689− it "openCursor(Nothing, Prev)" do
690− let dbName = "db-openCursor"
694− autoIncrement = true
696− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
698− _ <- IDBObjectStore.openCursor store Nothing Prev
702− db <- IDBFactory.open dbName Nothing
703− { onUpgradeNeeded : Just callback
704− , onBlocked : Nothing
706− tearDown dbName dbVersion db
708− it "openCursor(Nothing, PrevUnique)" do
709− let dbName = "db-openCursor"
713− autoIncrement = true
715− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
717− _ <- IDBObjectStore.openCursor store Nothing PrevUnique
721− db <- IDBFactory.open dbName Nothing
722− { onUpgradeNeeded : Just callback
723− , onBlocked : Nothing
725− tearDown dbName dbVersion db
727− it "openCursor(Just upperBound, Next)" do
728− let dbName = "db-openCursor"
732− autoIncrement = true
734− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
736− _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 10 true) Next
740− db <- IDBFactory.open dbName Nothing
741− { onUpgradeNeeded : Just callback
742− , onBlocked : Nothing
744− tearDown dbName dbVersion db
746− it "openKeyCursor(Nothing, Next)" do
747− let dbName = "db-openKeyCursor"
751− autoIncrement = true
753− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
755− _ <- IDBObjectStore.openKeyCursor store Nothing Next
759− db <- IDBFactory.open dbName Nothing
760− { onUpgradeNeeded : Just callback
761− , onBlocked : Nothing
763− tearDown dbName dbVersion db
765− it "openKeyCursor(Nothing, NextUnique)" do
766− let dbName = "db-openKeyCursor"
770− autoIncrement = true
772− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
774− _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique
778− db <- IDBFactory.open dbName Nothing
779− { onUpgradeNeeded : Just callback
780− , onBlocked : Nothing
782− tearDown dbName dbVersion db
784− it "openKeyCursor(Nothing, Prev)" do
785− let dbName = "db-openKeyCursor"
789− autoIncrement = true
791− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
793− _ <- IDBObjectStore.openKeyCursor store Nothing Prev
499+ _ <- IDBObjectStore.openCursor store Nothing Prev cb
794− pure unit
500+ _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
795− pure unit
501+ _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
797− db <- IDBFactory.open dbName Nothing
798− { onUpgradeNeeded : Just callback
799− , onBlocked : Nothing
801− tearDown dbName dbVersion db
803− it "openKeyCursor(Nothing, PrevUnique)" do
804− let dbName = "db-openKeyCursor"
808− autoIncrement = true
810− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
812− _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique
813 pure unit
502 pure unit
816− db <- IDBFactory.open dbName Nothing
817− { onUpgradeNeeded : Just callback
818− , onBlocked : Nothing
820− tearDown dbName dbVersion db
504+ tearDown db
822− it "openKeyCursor(Just upperBound, Next)" do
506+ it "openKeyCursor()" do
823− let dbName = "db-openKeyCursor"
507+ let
824− dbVersion = 1
508+ cb =
825− storeName = "store"
509+ { onSuccess: const $ pure unit
826− keyPath = []
510+ , onError: show >>> fail >>> launchAff'
827− autoIncrement = true
511+ , onComplete: pure unit
828− callback db = do
512+ }
829− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
513+ { db } <- setup
830− _ <- launchAff $ do
514+ { storeParams: IDBDatabase.defaultParameters
515+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
516+ _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
517+ _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
518+ _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
519+ _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
831− _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.upperBound 10 true) Next
520+ _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
832 pure unit
521 pure unit
835− db <- IDBFactory.open dbName Nothing
524+
836− { onUpgradeNeeded : Just callback
525+ describe "IDBIndex" do
837− , onBlocked : Nothing
526+ let
838− }
527+ tearDown db = do
839− tearDown dbName dbVersion db
528+ IDBDatabase.close db
840−
529+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
841− it "store.autoIncrement[true]" do
530+ pure unit
842− let dbName = "db-autoIncrement"
531+
843− dbVersion = 1
532+ setup
844− storeName = "store"
533+ :: forall value
845− keyPath = []
534+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
846− autoIncrement = true
535+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
847− callback db = do
536+ , values :: Array (Tuple value (Maybe Key))
848− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
537+ , keyPath :: Array String
849− let autoIncrement' = IDBObjectStore.autoIncrement store
538+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
850− _ <- launchAff $ autoIncrement `shouldEqual` autoIncrement'
539+ }
851− pure unit
540+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
852−
541+ setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
853− db <- IDBFactory.open dbName Nothing
542+ let
854− { onUpgradeNeeded : Just callback
543+ onUpgradeNeeded' var db tx _ = launchAff' do
855− , onBlocked : Nothing
544+ store <- IDBDatabase.createObjectStore db "store" storeParams
856− }
545+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
857− tearDown dbName dbVersion db
546+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
858−
547+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
859− it "store.autoIncrement[false]" do
548+ AVar.put { db, index, store } var
860− let dbName = "db-autoIncrement"
549+
861− dbVersion = 1
550+ var <- AVar.empty
862− storeName = "store"
551+ _ <- IDBFactory.open "db" Nothing
863− keyPath = []
552+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
864− autoIncrement = false
553+ , onBlocked: Nothing
865− callback db = do
554+ }
866− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
555+ AVar.take var
867− let autoIncrement' = IDBObjectStore.autoIncrement store
556+
868− _ <- launchAff $ autoIncrement `shouldEqual` autoIncrement'
557+ it "returns an IDBIndex and the properties are set correctly" do
869− pure unit
558+ { db, index } <- setup
870−
559+ { storeParams: IDBDatabase.defaultParameters
871− db <- IDBFactory.open dbName Nothing
560+ , indexParams: IDBObjectStore.defaultParameters
872− { onUpgradeNeeded : Just callback
561+ , onUpgradeNeeded: Nothing
873− , onBlocked : Nothing
562+ , keyPath: []
875− tearDown dbName dbVersion db
564+ }
876−
565+ IDBIndex.name index `shouldEqual` "index"
877− it "store.keyPath[\"patate\"]" do
566+ IDBIndex.keyPath index `shouldEqual` []
878− let dbName = "db-keyPath"
567+ IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
879− dbVersion = 1
568+ IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
880− storeName = "store"
569+ tearDown db
881− keyPath = ["patate"]
570+
882− autoIncrement = false
571+ it "attempt to create an index that requires unique values on an object store already contains duplicates" do
883− callback db = do
572+ let onAbort var = launchAff' (AVar.put true var)
884− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
573+ txVar <- AVar.empty
885− let keyPath' = IDBObjectStore.keyPath store
574+ dbVar <- AVar.empty
886− _ <- launchAff $ keyPath `shouldEqual` keyPath'
575+ res <- attempt $ setup
887− pure unit
576+ { storeParams: IDBDatabase.defaultParameters
889− db <- IDBFactory.open dbName Nothing
578+ { unique: true
890− { onUpgradeNeeded : Just callback
579+ , multiEntry: false
891− , onBlocked : Nothing
580+ }
892− }
581+ , keyPath: [ "indexedProperty" ]
893− tearDown dbName dbVersion db
582+ , values:
894−
583+ [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
895− it "store.indexNames[]" do
584+ , { indexedProperty: "bar" } :+: (Just $ toKey 2)
896− let dbName = "db-indexNames"
585+ ]
897− dbVersion = 1
586+ , onUpgradeNeeded: Just $ \db tx _ -> launchAff' do
898− storeName = "store"
587+ IDBTransaction.onAbort tx (onAbort txVar)
899− keyPath = []
588+ IDBDatabase.onAbort db (onAbort dbVar)
900− autoIncrement = false
589+ }
901− callback db = do
590+ case res of
902− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
591+ Right _ ->
903− let indexNames = IDBObjectStore.indexNames store
592+ fail "expected abort"
904− _ <- launchAff $ indexNames `shouldEqual` []
593+ _ -> do
905− pure unit
594+ shouldEqual true =<< AVar.take txVar
906−
595+ shouldEqual true =<< AVar.take dbVar
907− db <- IDBFactory.open dbName Nothing
596+
908− { onUpgradeNeeded : Just callback
597+ it "the index is usable right after being made" do
909− , onBlocked : Nothing
598+ { db } <- setup
910− }
599+ { storeParams:
911− tearDown dbName dbVersion db
600+ { keyPath: [ "key" ]
912−
601+ , autoIncrement: false
913− it "store.name[\"store\"]" do
602+ }
914− let dbName = "db-indexNames"
603+ , indexParams: IDBObjectStore.defaultParameters
915− dbVersion = 1
604+ , keyPath: [ "indexedProperty" ]
916− storeName = "store"
605+ , values:
917− keyPath = []
606+ [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
918− autoIncrement = false
607+ , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
919− callback db = do
608+ , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
920− store <- IDBDatabase.createObjectStore db storeName { keyPath, autoIncrement }
609+ ]
921− let storeName' = IDBObjectStore.name store
610+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
922− _ <- launchAff $ storeName `shouldEqual` storeName'
611+ val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
923− pure unit
612+ ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
616+ it "empty keyPath" do
618+ { storeParams: IDBDatabase.defaultParameters
619+ , indexParams: IDBObjectStore.defaultParameters
622+ [ "object_1" :+: (Just $ toKey 1)
623+ , "object_2" :+: (Just $ toKey 2)
624+ , "object_3" :+: (Just $ toKey 3)
626+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
627+ val <- IDBIndex.get index (IDBKeyRange.only "object_3")
628+ val `shouldEqual` (Just "object_3")
632+ it "index can be valid keys [date]" do
633+ date <- liftEffect $ toDateTime <$> now
636+ { keyPath: [ "key" ]
637+ , autoIncrement: false
639+ , indexParams: IDBObjectStore.defaultParameters
642+ [ { key: "date", i: (toKey date) } :+: Nothing
644+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
645+ val <- IDBIndex.get index (IDBKeyRange.only date)
646+ ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
650+ it "index can be valid keys [num]" do
654+ { keyPath: [ "key" ]
655+ , autoIncrement: false
657+ , indexParams: IDBObjectStore.defaultParameters
660+ [ { key: "num", i: (toKey num) } :+: Nothing
662+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
663+ val <- IDBIndex.get index (IDBKeyRange.only num)
664+ ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
668+ it "index can be valid keys [array]" do
669+ let array = [ "patate", "autruche" ]
672+ { keyPath: [ "key" ]
673+ , autoIncrement: false
675+ , indexParams: IDBObjectStore.defaultParameters
678+ [ { key: "array", i: (toKey array) } :+: Nothing
680+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
681+ val <- IDBIndex.get index (IDBKeyRange.only array)
682+ ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
686+ it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
687+ res <- attempt $ setup
688+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
689+ , indexParams: IDBObjectStore.defaultParameters
690+ , keyPath: [ "indexedProperty" ]
692+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
694+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
697+ { onSuccess: const $ pure unit
698+ , onError: show >>> fail >>> launchAff'
699+ , onComplete: pure unit
701+ IDBTransaction.onAbort tx (pure unit)
702+ IDBDatabase.onAbort db (pure unit)
703+ IDBTransaction.abort tx
704+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
706+ Right _ -> fail "expected InvalidStateError"
707+ Left err -> name err `shouldEqual` "InvalidStateError"
710+ Right _ -> fail "expected InvalidStateError"
713+ it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
715+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
716+ , indexParams: IDBObjectStore.defaultParameters
717+ , keyPath: [ "indexedProperty" ]
719+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
721+ , onUpgradeNeeded: Nothing
725+ { onSuccess: const $ pure unit
726+ , onError: show >>> fail >>> launchAff'
727+ , onComplete: pure unit
729+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
730+ store <- IDBTransaction.objectStore tx "store"
731+ index <- IDBObjectStore.index store "index"
732+ IDBTransaction.onAbort tx (pure unit)
733+ IDBTransaction.abort tx
734+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
736+ Right _ -> fail "expected TransactionInactiveError"
737+ Left err -> name err `shouldEqual` "TransactionInactiveError"
741+ it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
743+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
744+ , indexParams: IDBObjectStore.defaultParameters
745+ , keyPath: [ "indexedProperty" ]
747+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
749+ , onUpgradeNeeded: Just $ \_ tx index -> launchAff' do
752+ { onSuccess: const $ pure unit
753+ , onError: show >>> fail >>> launchAff'
754+ , onComplete: pure unit
756+ store <- IDBTransaction.objectStore tx "store"
757+ IDBObjectStore.deleteIndex store "index"
758+ cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
760+ Right _ -> fail "expected InvalidStateError"
761+ Left err -> name err `shouldEqual` "InvalidStateError"
766+ it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
767+ res <- attempt $ setup
768+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
769+ , indexParams: IDBObjectStore.defaultParameters
770+ , keyPath: [ "indexedProperty" ]
772+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
774+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
777+ { onSuccess: const $ pure unit
778+ , onError: show >>> fail >>> launchAff'
779+ , onComplete: pure unit
781+ IDBTransaction.onAbort tx (pure unit)
782+ IDBDatabase.onAbort db (pure unit)
783+ IDBTransaction.abort tx
784+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
786+ Right _ -> fail "expected InvalidStateError"
787+ Left err -> name err `shouldEqual` "InvalidStateError"
790+ Right _ -> fail "expected InvalidStateError"
793+ it "openCursor() - throw TransactionInactiveError on aborted transaction" do
795+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
796+ , indexParams: IDBObjectStore.defaultParameters
797+ , keyPath: [ "indexedProperty" ]
799+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
801+ , onUpgradeNeeded: Nothing
805+ { onSuccess: const $ pure unit
806+ , onError: show >>> fail >>> launchAff'
807+ , onComplete: pure unit
809+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
810+ store <- IDBTransaction.objectStore tx "store"
811+ index <- IDBObjectStore.index store "index"
812+ IDBTransaction.onAbort tx (pure unit)
813+ IDBTransaction.abort tx
814+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
816+ Right _ -> fail "expected TransactionInactiveError"
817+ Left err -> name err `shouldEqual` "TransactionInactiveError"
821+ it "openCursor() - throw InvalidStateError when the index is deleted" do
823+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
824+ , indexParams: IDBObjectStore.defaultParameters
825+ , keyPath: [ "indexedProperty" ]
827+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
829+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
832+ { onSuccess: const $ pure unit
833+ , onError: show >>> fail >>> launchAff'
834+ , onComplete: pure unit
836+ store <- IDBTransaction.objectStore tx "store"
837+ IDBObjectStore.deleteIndex store "index"
838+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
840+ Right _ -> fail "expected InvalidStateError"
841+ Left err -> name err `shouldEqual` "InvalidStateError"
846+ it "getKey() - multiEntry - adding keys" do
848+ { storeParams: IDBDatabase.defaultParameters
849+ , indexParams: { unique: false, multiEntry: true }
850+ , keyPath: [ "name" ]
852+ [ { name: [ "patate", "autruche" ] } :+: (Just $ toKey 1)
853+ , { name: [ "bob" ] } :+: (Just $ toKey 2)
855+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
856+ key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
857+ key `shouldEqual` (Just $ toKey 1)
859+ key' <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
860+ key' `shouldEqual` (Just $ toKey 1)
862+ key'' <- IDBIndex.getKey index (IDBKeyRange.only "bob")
863+ key'' `shouldEqual` (Just $ toKey 2)
867+ it "get() - returns the record with the first key in the range" do
869+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
870+ , indexParams: IDBObjectStore.defaultParameters
871+ , keyPath: [ "indexedProperty" ]
873+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
874+ , { key: 42, indexedProperty: "autruche" } :+: Nothing
875+ , { key: 1337, indexedProperty: "baguette" } :+: Nothing
877+ , onUpgradeNeeded: Nothing
880+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
881+ store <- IDBTransaction.objectStore tx "store"
882+ index <- IDBObjectStore.index store "index"
883+ val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
884+ ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
888+ describe "IDBCursor" do
891+ IDBDatabase.close db
892+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
897+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
898+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
899+ , values :: Array (Tuple value (Maybe Key))
900+ , keyPath :: Array String
901+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
903+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
904+ setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
906+ onUpgradeNeeded' var db tx _ = launchAff' do
907+ store <- IDBDatabase.createObjectStore db "store" storeParams
908+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
909+ index <- IDBObjectStore.createIndex store "index" keyPath indexParams
910+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
911+ AVar.put { db, index, store } var
914+ db <- IDBFactory.open "db" Nothing
915+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
916+ , onBlocked: Nothing
920+ it "continue() - iterate to the next record" do
922+ { storeParams: IDBDatabase.defaultParameters
923+ , indexParams: IDBObjectStore.defaultParameters
926+ [ "cupcake" :+: (Just $ toKey 4)
927+ , "pancake" :+: (Just $ toKey 2)
928+ , "pie" :+: (Just $ toKey 1)
929+ , "pie" :+: (Just $ toKey 3)
931+ , onUpgradeNeeded: Nothing
935+ { onComplete: launchAff' do
938+ , onError: \error -> launchAff' do
939+ fail $ "unexpected error: " <> show error
941+ , onSuccess: \cursor -> launchAff' do
942+ vals <- AVar.take vvals
943+ pure (IDBCursor.value cursor) >>= shouldEqual (maybe "" _.v $ head vals)
944+ IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
945+ AVar.put (drop 1 vals) vvals
946+ IDBCursor.continue cursor none
950+ [ { v: "pie", k: toKey 1 }
951+ , { v: "pancake", k: toKey 2 }
952+ , { v: "pie", k: toKey 3 }
953+ , { v: "cupcake", k: toKey 4 }
955+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
956+ store <- IDBTransaction.objectStore tx "store"
957+ IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
961+ it "continue() - attempt to iterate in the wrong direction" do
963+ { storeParams: IDBDatabase.defaultParameters
964+ , indexParams: IDBObjectStore.defaultParameters
967+ [ "cupcake" :+: (Just $ toKey 4)
968+ , "pancake" :+: (Just $ toKey 2)
969+ , "pie" :+: (Just $ toKey 1)
970+ , "pie" :+: (Just $ toKey 3)
972+ , onUpgradeNeeded: Nothing
976+ { onComplete: launchAff' do
977+ fail $ "shouldn't complete"
979+ , onError: \error -> launchAff' do
980+ fail $ "unexpected error: " <> show error
982+ , onSuccess: \cursor -> launchAff' do
983+ res <- attempt $ IDBCursor.continue cursor (Just 1)
986+ name err `shouldEqual` "DataError"
989+ fail "expected continue to fail"
992+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
993+ store <- IDBTransaction.objectStore tx "store"
994+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
998+ it "advance() - iterate cursor number of times specified by count" do
1000+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1001+ , indexParams: IDBObjectStore.defaultParameters
1004+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1005+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1006+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1007+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1009+ , onUpgradeNeeded: Nothing
1013+ { onComplete: launchAff' do
1014+ AVar.put unit vdone
1016+ , onError: \error -> launchAff' do
1017+ fail $ "unexpected error: " <> show error
1019+ , onSuccess: \cursor -> launchAff' do
1020+ jump <- AVar.take vjump
1022+ IDBCursor.advance cursor 3
1024+ let value = IDBCursor.value cursor
1025+ value.pKey `shouldEqual` "pkey_3"
1026+ value.iKey `shouldEqual` "ikey_3"
1027+ IDBCursor.continue cursor none
1028+ AVar.put false vjump
1030+ vdone <- AVar.empty
1031+ vjump <- AVar.new true
1032+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1033+ store <- IDBTransaction.objectStore tx "store"
1034+ IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
1038+ it "delete() - remove a record from the object store" do
1040+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1041+ , indexParams: IDBObjectStore.defaultParameters
1044+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1045+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1046+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1047+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1049+ , onUpgradeNeeded: Nothing
1053+ { onComplete: launchAff' do
1054+ mval <- map _.pKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1055+ mval `shouldEqual` (Nothing :: Maybe String)
1056+ AVar.put unit vdone
1058+ , onError: \error -> launchAff' do
1059+ fail $ "unexpected error: " <> show error
1061+ , onSuccess: \cursor -> launchAff' do
1062+ let value = IDBCursor.value cursor
1063+ value.pKey `shouldEqual` "pkey_0"
1064+ IDBCursor.delete cursor
1065+ IDBCursor.advance cursor 4
1067+ vdone <- AVar.empty
1068+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1069+ store <- IDBTransaction.objectStore tx "store"
1070+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1074+ it "update() - modify a record in the object store" do
1076+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1077+ , indexParams: IDBObjectStore.defaultParameters
1080+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1082+ , onUpgradeNeeded: Nothing
1086+ { onComplete: launchAff' do
1087+ mval <- map _.iKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1088+ mval `shouldEqual` (Just "patate")
1089+ AVar.put unit vdone
1091+ , onError: \error -> launchAff' do
1092+ fail $ "unexpected error: " <> show error
1094+ , onSuccess: \cursor -> launchAff' do
1095+ let value = IDBCursor.value cursor
1096+ value.pKey `shouldEqual` "pkey_0"
1097+ key <- IDBCursor.update cursor { pKey: "pkey_0", iKey: "patate" }
1098+ key `shouldEqual` toKey "pkey_0"
1099+ IDBCursor.advance cursor 4
1101+ vdone <- AVar.empty
1102+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1103+ store <- IDBTransaction.objectStore tx "store"
1104+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1108+ it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1110+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1111+ , indexParams: IDBObjectStore.defaultParameters
1114+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1116+ , onUpgradeNeeded: Nothing
1120+ { onComplete: launchAff' do
1121+ fail $ "shouldn't complete"
1123+ , onError: \error -> launchAff' do
1124+ fail $ "unexpected error: " <> show error
1126+ , onSuccess: \cursor -> launchAff' do
1127+ res <- attempt $ IDBCursor.update cursor "patate"
1130+ name err `shouldEqual` "ReadOnlyError"
1131+ AVar.put unit vdone
1133+ fail $ "expected ReadOnlyError"
1135+ vdone <- AVar.empty
1136+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1137+ store <- IDBTransaction.objectStore tx "store"
1138+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
925− db <- IDBFactory.open dbName Nothing
926− { onUpgradeNeeded : Just callback
927− , onBlocked : Nothing
929− tearDown dbName dbVersion db