@@ -2,1079 +2,1139 @@ module Test.Main where
3import Prelude
3import Prelude
5−import Control.Monad.Aff (Aff, launchAff, launchAff_, forkAff, delay, attempt)
5+import Data.Array (head, drop)
6−import Control.Monad.Aff.AVar (AVAR, AVar, makeVar, makeEmptyVar, readVar, putVar, takeVar)
7−import Control.Monad.Aff.Console (log)
8−import Control.Monad.Eff (Eff)
9−import Control.Monad.Eff.Class (liftEff)
10−import Control.Monad.Eff.Exception (EXCEPTION, name)
11−import Control.Monad.Eff.Now (NOW, now)
12−import Data.Date as Date
6+import Data.Date as Date
13−import Data.DateTime as DateTime
7+import Data.DateTime (DateTime(..), Time(..))
14−import Data.DateTime (DateTime(..), Time(..))
15−import Data.DateTime.Instant (toDateTime)
8+import Data.DateTime.Instant (toDateTime)
16−import Data.Either (Either(..))
9+import Data.Either (Either(..))
17−import Data.Enum (toEnum)
10+import Data.Enum (toEnum)
18−import Data.Maybe (Maybe(..), isNothing, maybe)
11+import Data.Maybe (Maybe(..), isNothing, maybe)
19−import Data.Array (head, drop)
20−import Data.Time.Duration (Milliseconds(..))
12+import Data.Time.Duration (Milliseconds(..))
21−import Data.Traversable (traverse)
13+import Data.Traversable (traverse)
22−import Data.Tuple (Tuple(..), uncurry)
14+import Data.Tuple (Tuple(..), uncurry)
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
20+import Database.IndexedDB.IDBKey (Key, none, toKey)
21+import Database.IndexedDB.IDBKeyRange as IDBKeyRange
22+import Database.IndexedDB.IDBObjectStore as IDBObjectStore
23+import Database.IndexedDB.IDBTransaction as IDBTransaction
24+import Effect (Effect)
25+import Effect.Aff (Aff, attempt, delay, forkAff, launchAff, launchAff_)
26+import Effect.Aff.AVar (AVar)
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)
23−import Test.Spec (describe, describeOnly, it)
32+import Test.Spec (describe, it)
24−import Test.Spec.Assertions (shouldEqual, fail)
33+import Test.Spec.Assertions (shouldEqual, fail)
25−import Test.Spec.Mocha (MOCHA, runMocha)
34+import Test.Spec.Mocha (runMocha)
27−import Database.IndexedDB.Core
28−import Database.IndexedDB.IDBKey
29−import Database.IndexedDB.IDBCursor as IDBCursor
30−import Database.IndexedDB.IDBDatabase as IDBDatabase
31−import Database.IndexedDB.IDBFactory as IDBFactory
32−import Database.IndexedDB.IDBIndex as IDBIndex
33−import Database.IndexedDB.IDBKeyRange as IDBKeyRange
34−import Database.IndexedDB.IDBObjectStore as IDBObjectStore
35−import Database.IndexedDB.IDBTransaction as IDBTransaction
38infixr 7 Tuple as :+:
36infixr 7 Tuple as :+:
40−launchAff' :: forall a e. Aff e a -> Eff e Unit
38+launchAff' :: forall a. Aff a -> Effect Unit
41launchAff' =
39launchAff' =
42− launchAff_
40+ launchAff_ <<< void
42+modifyAVar :: forall a. (a -> a) -> AVar a -> Aff Unit
51+ describe "IDBFactory" do
53+ tearDown name version db = do
55+ version' <- IDBFactory.deleteDatabase name
56+ liftEffect $ log $ show version'
57+ version' `shouldEqual` version
63+ db <- IDBFactory.open name Nothing
64+ { onUpgradeNeeded: Nothing
67+ IDBDatabase.name db `shouldEqual` name
68+ tearDown name version db
70+ it "open specific version" do
74+ db <- IDBFactory.open name (Just version)
75+ { onUpgradeNeeded: Nothing
78+ IDBDatabase.name db `shouldEqual` name
79+ tearDown name version db
81+ it "open specific version -> close -> open latest" do
85+ db01 <- IDBFactory.open name (Just version)
86+ { onUpgradeNeeded: Nothing
89+ IDBDatabase.name db01 `shouldEqual` name
90+ IDBDatabase.close db01
91+ db02 <- IDBFactory.open name Nothing
92+ { onUpgradeNeeded: Nothing
95+ tearDown name version db02
97+ it "open + onUpgradeNeed" do
99+ name = "db-upgrade-needed"
101+ callback (Tuple varName varVersion) db _ { oldVersion } = do
102+ _ <- launchAff $ modifyAVar (const $ IDBDatabase.name db) varName
103+ _ <- launchAff $ modifyAVar (const $ oldVersion) varVersion
105+ varName <- AVar.new "-"
106+ varVersion <- AVar.new (-1)
107+ db <- IDBFactory.open name Nothing
108+ { onUpgradeNeeded: Just (callback (Tuple varName varVersion))
109+ , onBlocked: Nothing
111+ name' <- AVar.read varName
112+ version' <- AVar.read varVersion
113+ name' `shouldEqual` name
114+ version' `shouldEqual` 0
115+ tearDown name version db
117+ it "open + onBlocked" do
122+ _ <- launchAff $ modifyAVar (const $ "db-blocked") var
126+ db01 <- IDBFactory.open name Nothing
127+ { onUpgradeNeeded: Nothing
128+ , onBlocked: Nothing
131+ delay (Milliseconds 100.0)
132+ IDBDatabase.close db01
134+ db02 <- IDBFactory.open name (Just version)
135+ { onUpgradeNeeded: Nothing
136+ , onBlocked: Just (callback var)
138+ name' <- AVar.read var
139+ name' `shouldEqual` name
140+ tearDown name version db02
142+ describe "IDBKeyRange" do
146+ range = IDBKeyRange.only key
147+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
45−modifyVar :: forall eff a. (a -> a) -> AVar a -> Aff (avar :: AVAR | eff) Unit
149+ it "only(string)" do
46−modifyVar fn v = do
150+ let
47− val <- takeVar v
151+ key = "patate"
48− putVar (fn val) v
152+ range = IDBKeyRange.only key
153+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
158+ range = IDBKeyRange.only key
159+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
51−-- main :: forall eff. Eff (now :: NOW, mocha :: MOCHA, idb :: IDB, exception :: EXCEPTION, avar :: AVAR | eff) Unit
161+ it "only(date)" do
52−main = runMocha do
162+ let
53− describe "IDBFactory" do
163+ mkey = DateTime
54− let
164+ <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
55− tearDown name version db = do
165+ <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
56− IDBDatabase.close db
166+
57− version' <- IDBFactory.deleteDatabase name
167+ case mkey of
58− version' `shouldEqual` version
61− let name = "db-default"
63− db <- IDBFactory.open name Nothing
64− { onUpgradeNeeded : Nothing
65− , onBlocked : Nothing
67− IDBDatabase.name db `shouldEqual` name
68− tearDown name version db
71− it "open specific version" do
72− let name = "db-specific"
74− db <- IDBFactory.open name (Just version)
75− { onUpgradeNeeded : Nothing
76− , onBlocked : Nothing
78− IDBDatabase.name db `shouldEqual` name
79− tearDown name version db
82− it "open specific version -> close -> open latest" do
83− let name = "db-latest"
85− db01 <- IDBFactory.open name (Just version)
86− { onUpgradeNeeded : Nothing
87− , onBlocked : Nothing
89− IDBDatabase.name db01 `shouldEqual` name
90− IDBDatabase.close db01
91− db02 <- IDBFactory.open name Nothing
92− { onUpgradeNeeded : Nothing
93− , onBlocked : Nothing
95− tearDown name version db02
97− it "open + onUpgradeNeed" do
98− let name = "db-upgrade-needed"
100− callback (Tuple varName varVersion) db _ { oldVersion } = do
101− _ <- launchAff $ modifyVar (const $ IDBDatabase.name db) varName
102− _ <- launchAff $ modifyVar (const $ oldVersion) varVersion
104− varName <- makeVar "-"
105− varVersion <- makeVar (-1)
106− db <- IDBFactory.open name Nothing
107− { onUpgradeNeeded : Just (callback (Tuple varName varVersion))
108− , onBlocked : Nothing
168+ Nothing ->
109− }
169+ fail "unable to create datetime"
110− name' <- readVar varName
170+ Just key -> do
111− version' <- readVar varVersion
171+ let range = IDBKeyRange.only key
112− name' `shouldEqual` name
172+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
113− version' `shouldEqual` 0
173+
114− tearDown name version db
174+ it "only([int])" do
116− it "open + onBlocked" do
176+ key = [ 14, 42 ]
117− let name = "db-blocked"
177+ range = IDBKeyRange.only key
118− version = 14
178+ IDBKeyRange.includes range (toKey key) `shouldEqual` true
120− _ <- launchAff $ modifyVar (const $ "db-blocked") var
124− db01 <- IDBFactory.open name Nothing
125− { onUpgradeNeeded : Nothing
126− , onBlocked : Nothing
129− delay (Milliseconds 100.0)
130− IDBDatabase.close db01
132− db02 <- IDBFactory.open name (Just version)
133− { onUpgradeNeeded : Nothing
134− , onBlocked : Just (callback var)
136− name' <- readVar var
137− name' `shouldEqual` name
138− tearDown name version db02
140− describe "IDBKeyRange" do
143− range = IDBKeyRange.only key
144− IDBKeyRange.includes range (toKey key) `shouldEqual` true
146− it "only(string)" do
180+ it "only([string])" do
147− let key = "patate"
182+ key = [ "patate", "autruche" ]
148− range = IDBKeyRange.only key
149− IDBKeyRange.includes range (toKey key) `shouldEqual` true
153− range = IDBKeyRange.only key
154− IDBKeyRange.includes range (toKey key) `shouldEqual` true
158− <$> (Date.canonicalDate <$> toEnum 2017 <*> toEnum 6 <*> toEnum 23)
159− <*> (Time <$> toEnum 17 <*> toEnum 59 <*> toEnum 34 <*> toEnum 42)
163− fail "unable to create datetime"
165− let range = IDBKeyRange.only key
183+ range = IDBKeyRange.only key
166 IDBKeyRange.includes range (toKey key) `shouldEqual` true
184 IDBKeyRange.includes range (toKey key) `shouldEqual` true
168− it "only([int])" do
186+ it "lowerBound(14, open)" do
169− let key = [14, 42]
187+ let
170− range = IDBKeyRange.only key
188+ key = 14
171− IDBKeyRange.includes range (toKey key) `shouldEqual` true
173− it "only([string])" do
174− let key = ["patate", "autruche"]
175− range = IDBKeyRange.only key
176− IDBKeyRange.includes range (toKey key) `shouldEqual` true
178− it "lowerBound(14, open)" do
180− open = true
189+ open = true
181− range = IDBKeyRange.lowerBound key open
190+ range = IDBKeyRange.lowerBound key open
182− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
191+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
183− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
192+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
184− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
193+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
186− it "lowerBound(14, close)" do
195+ it "lowerBound(14, close)" do
187− let key = 14
197+ key = 14
188− open = false
198+ open = false
189− range = IDBKeyRange.lowerBound key open
199+ range = IDBKeyRange.lowerBound key open
190− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
200+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` true
191− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
201+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
192− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
202+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` false
194− it "upperBound(14, open)" do
204+ it "upperBound(14, open)" do
195− let key = 14
205+ let
196− open = true
207+ open = true
197− range = IDBKeyRange.upperBound key open
208+ range = IDBKeyRange.upperBound key open
198− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
209+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
199− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
210+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
200− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
211+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
202− it "upperBound(14, close)" do
213+ it "upperBound(14, close)" do
203− let key = 14
214+ let
204− open = false
216+ open = false
205− range = IDBKeyRange.upperBound key open
217+ range = IDBKeyRange.upperBound key open
206− IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
218+ IDBKeyRange.includes range (toKey (key + 1)) `shouldEqual` false
207− IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
219+ IDBKeyRange.includes range (toKey key) `shouldEqual` (not open)
208− IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
220+ IDBKeyRange.includes range (toKey (key - 1)) `shouldEqual` true
210− it "bound(42, 14, open, open) => Nothing" do
222+ it "bound(42, 14, open, open) => Nothing" do
211− let lower = 42
224+ lower = 42
212− upper = 14
225+ upper = 14
213− lowerOpen = true
226+ lowerOpen = true
214− upperOpen = true
227+ upperOpen = true
215− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
228+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
216− isNothing mrange `shouldEqual` true
229+ isNothing mrange `shouldEqual` true
218− it "bound(14, 42, open, open)" do
231+ it "bound(14, 42, open, open)" do
219− let lower = 14
232+ let
220− upper = 42
234+ upper = 42
221− lowerOpen = true
235+ lowerOpen = true
222− upperOpen = true
236+ upperOpen = true
223− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
237+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
224− case mrange of
238+ case mrange of
225− Nothing ->
239+ Nothing ->
226− fail "invalid range provided"
240+ fail "invalid range provided"
227− Just range -> do
241+ Just range -> do
228− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
242+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
229− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
243+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
230− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
244+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
231− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
245+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
232− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
246+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
233− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
247+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
235− it "bound(14, 42, open, close)" do
249+ it "bound(14, 42, open, close)" do
236− let lower = 14
250+ let
237− upper = 42
252+ upper = 42
238− lowerOpen = true
253+ lowerOpen = true
239− upperOpen = false
254+ upperOpen = false
240− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
255+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
241− case mrange of
256+ case mrange of
242− Nothing ->
257+ Nothing ->
243− fail "invalid range provided"
258+ fail "invalid range provided"
244− Just range -> do
259+ Just range -> do
245− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
260+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
246− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
261+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
247− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
262+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
248− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
263+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
249− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
264+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
250− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
265+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
252− it "bound(14, 42, close, open)" do
267+ it "bound(14, 42, close, open)" do
253− let lower = 14
268+ let
254− upper = 42
270+ upper = 42
255− lowerOpen = false
271+ lowerOpen = false
256− upperOpen = true
272+ upperOpen = true
257− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
273+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
258− case mrange of
274+ case mrange of
259− Nothing ->
275+ Nothing ->
260− fail "invalid range provided"
276+ fail "invalid range provided"
261− Just range -> do
277+ Just range -> do
262− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
278+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
263− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
279+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
264− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
280+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
265− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
281+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
266− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
282+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
267− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
283+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
269− it "bound(14, 42, close, close)" do
285+ it "bound(14, 42, close, close)" do
270− let lower = 14
286+ let
271− upper = 42
288+ upper = 42
272− lowerOpen = false
289+ lowerOpen = false
273− upperOpen = false
290+ upperOpen = false
274− mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
291+ mrange = IDBKeyRange.bound { lower, upper, lowerOpen, upperOpen }
275− case mrange of
292+ case mrange of
276− Nothing ->
293+ Nothing ->
277− fail "invalid range provided"
294+ fail "invalid range provided"
278− Just range -> do
295+ Just range -> do
279− IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
296+ IDBKeyRange.includes range (toKey (lower + 1)) `shouldEqual` true
280− IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
297+ IDBKeyRange.includes range (toKey (upper - 1)) `shouldEqual` true
281− IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
298+ IDBKeyRange.includes range (toKey (lower - 1)) `shouldEqual` false
282− IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
299+ IDBKeyRange.includes range (toKey (upper + 1)) `shouldEqual` false
283− IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
300+ IDBKeyRange.includes range (toKey lower) `shouldEqual` (not lowerOpen)
284− IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
301+ IDBKeyRange.includes range (toKey upper) `shouldEqual` (not upperOpen)
286− it "can access attributes of a range" do
303+ it "can access attributes of a range" do
287− let range = IDBKeyRange.lowerBound 14 false
304+ let range = IDBKeyRange.lowerBound 14 false
288− IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
305+ IDBKeyRange.lower range `shouldEqual` (Just $ toKey 14)
289− IDBKeyRange.upper range `shouldEqual` none
306+ IDBKeyRange.upper range `shouldEqual` none
290− IDBKeyRange.lowerOpen range `shouldEqual` false
307+ IDBKeyRange.lowerOpen range `shouldEqual` false
291− IDBKeyRange.upperOpen range `shouldEqual` true
308+ IDBKeyRange.upperOpen range `shouldEqual` true
293− describe "IDBDatabase" do
310+ describe "IDBDatabase" do
295− tearDown db = do
312+ tearDown db = do
296− IDBDatabase.close db
313+ IDBDatabase.close db
297− _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
314+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
298− pure unit
315+ pure unit
300− setup storeParams = do
317+ setup storeParams = do
301− let onUpgradeNeeded var db _ _ = launchAff' do
319+ onUpgradeNeeded var db _ _ = launchAff' do
302 store <- IDBDatabase.createObjectStore db "store" storeParams
320 store <- IDBDatabase.createObjectStore db "store" storeParams
303− _ <- putVar { db, store } var
321+ _ <- AVar.put { db, store } var
304 pure unit
322 pure unit
306− var <- makeEmptyVar
324+ var <- AVar.empty
307− db <- IDBFactory.open "db" Nothing
325+ _ <- IDBFactory.open "db" Nothing
308− { onUpgradeNeeded : Just (onUpgradeNeeded var)
326+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
309− , onBlocked : Nothing
327+ , onBlocked: Nothing
312− takeVar var
330+ AVar.take var
314− it "createObjectStore (keyPath: [], autoIncrement: true)" do
332+ it "createObjectStore (keyPath: [], autoIncrement: true)" do
315− { db, store } <- setup { keyPath: [], autoIncrement: true }
333+ { db, store } <- setup { keyPath: [], autoIncrement: true }
316− IDBObjectStore.name store `shouldEqual` "store"
334+ IDBObjectStore.name store `shouldEqual` "store"
317− IDBObjectStore.keyPath store `shouldEqual` []
335+ IDBObjectStore.keyPath store `shouldEqual` []
318− IDBObjectStore.autoIncrement store `shouldEqual` true
336+ IDBObjectStore.autoIncrement store `shouldEqual` true
319− IDBObjectStore.indexNames store `shouldEqual` []
337+ IDBObjectStore.indexNames store `shouldEqual` []
320− tearDown db
338+ tearDown db
322− it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
340+ it "createObjectStore (keyPath: [\"patate\"], autoIncrement: true)" do
323− { db, store } <- setup { keyPath: ["patate"], autoIncrement: true }
341+ { db, store } <- setup { keyPath: [ "patate" ], autoIncrement: true }
324− IDBObjectStore.name store `shouldEqual` "store"
342+ IDBObjectStore.name store `shouldEqual` "store"
325− IDBObjectStore.keyPath store `shouldEqual` ["patate"]
343+ IDBObjectStore.keyPath store `shouldEqual` [ "patate" ]
326− IDBObjectStore.autoIncrement store `shouldEqual` true
344+ IDBObjectStore.autoIncrement store `shouldEqual` true
327− IDBObjectStore.indexNames store `shouldEqual` []
345+ IDBObjectStore.indexNames store `shouldEqual` []
328− tearDown db
346+ tearDown db
330− it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
348+ it "createObjectStore (keyPath: [\"a\", \"b\"], autoIncrement: false)" do
331− { db, store } <- setup { keyPath: ["patate", "autruche"], autoIncrement: false }
349+ { db, store } <- setup { keyPath: [ "patate", "autruche" ], autoIncrement: false }
332− IDBObjectStore.name store `shouldEqual` "store"
350+ IDBObjectStore.name store `shouldEqual` "store"
333− IDBObjectStore.keyPath store `shouldEqual` ["patate", "autruche"]
351+ IDBObjectStore.keyPath store `shouldEqual` [ "patate", "autruche" ]
334− IDBObjectStore.autoIncrement store `shouldEqual` false
352+ IDBObjectStore.autoIncrement store `shouldEqual` false
335− IDBObjectStore.indexNames store `shouldEqual` []
353+ IDBObjectStore.indexNames store `shouldEqual` []
336− tearDown db
354+ tearDown db
338− it "deleteObjectStore" do
356+ it "deleteObjectStore" do
339− let onUpgradeNeeded var db _ _ = launchAff' do
358+ onUpgradeNeeded var db _ _ = launchAff' do
340− _ <- IDBDatabase.deleteObjectStore db "store"
359+ _ <- IDBDatabase.deleteObjectStore db "store"
341− putVar true var
360+ AVar.put true var
343− var <- makeEmptyVar
362+ var <- AVar.empty
344− { db, store } <- setup IDBDatabase.defaultParameters
363+ { db } <- setup IDBDatabase.defaultParameters
345− IDBDatabase.close db
346− db' <- IDBFactory.open "db" (Just 999) { onUpgradeNeeded : Just (onUpgradeNeeded var)
347− , onBlocked : Nothing
349− deleted <- takeVar var
350− deleted `shouldEqual` true
354− describe "IDBObjectStore" do
357 IDBDatabase.close db
364 IDBDatabase.close db
365+ db' <- IDBFactory.open "db" (Just 999)
366+ { onUpgradeNeeded: Just (onUpgradeNeeded var)
367+ , onBlocked: Nothing
369+ deleted <- AVar.take var
370+ deleted `shouldEqual` true
373+ describe "IDBObjectStore" do
376+ IDBDatabase.close db
358− _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
377+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
359− pure unit
378+ pure unit
361− setup { storeParams, onUpgradeNeeded } = do
380+ setup { storeParams, onUpgradeNeeded } = do
362− let onUpgradeNeeded' var db _ _ = launchAff' do
382+ onUpgradeNeeded' var db _ _ = launchAff' do
363 store <- IDBDatabase.createObjectStore db "store" storeParams
383 store <- IDBDatabase.createObjectStore db "store" storeParams
364− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure store)
384+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure store)
365− putVar { db, store } var
385+ AVar.put { db, store } var
367− var <- makeEmptyVar
387+ var <- AVar.empty
368− db <- IDBFactory.open "db" Nothing
388+ _ <- IDBFactory.open "db" Nothing
369− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
389+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
370− , onBlocked : Nothing
390+ , onBlocked: Nothing
396+ date <- liftEffect $ toDateTime <$> now
398+ { storeParams: { autoIncrement: true, keyPath: [] }
399+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
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'''''
376− date <- liftEff $ toDateTime <$> now
378− { storeParams: { autoIncrement: true, keyPath: [] }
379− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
381− key <- IDBObjectStore.add store "patate" none
382− (toKey 1) `shouldEqual` key
385− key' <- IDBObjectStore.add store "patate" (Just 14)
386− (toKey 14) `shouldEqual` key'
389− key'' <- IDBObjectStore.add store "patate" (Just 14.42)
390− (toKey 14.42) `shouldEqual` key''
393− key''' <- IDBObjectStore.add store "patate" (Just "key")
394− (toKey "key") `shouldEqual` key'''
397− key'''' <- IDBObjectStore.add store "patate" (Just date)
398− (toKey date) `shouldEqual` key''''
401− key''''' <- IDBObjectStore.add store "patate" (Just $ toKey [14, 42])
402− (toKey [14, 42]) `shouldEqual` key'''''
406− it "clear()" do
426+ it "clear()" do
407− { db } <- setup
427+ { db } <- setup
408− { storeParams: IDBDatabase.defaultParameters
428+ { storeParams: IDBDatabase.defaultParameters
409− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
429+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
410− key <- IDBObjectStore.add store "patate" (Just 14)
430+ key <- IDBObjectStore.add store "patate" (Just 14)
411− _ <- IDBObjectStore.clear store
431+ _ <- IDBObjectStore.clear store
412− val <- IDBObjectStore.get store (IDBKeyRange.only key)
432+ val <- IDBObjectStore.get store (IDBKeyRange.only key)
413− val `shouldEqual` (Nothing :: Maybe String)
433+ val `shouldEqual` (Nothing :: Maybe String)
419− { storeParams: IDBDatabase.defaultParameters
420− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
421− _ <- IDBObjectStore.add store "patate" (Just 14)
422− _ <- IDBObjectStore.add store "autruche" (Just 42)
423− n <- IDBObjectStore.count store Nothing
430− { storeParams: IDBDatabase.defaultParameters
431− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
432− key <- IDBObjectStore.add store "patate" (Just 14)
433− mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
434− mkey `shouldEqual` (Just key)
436− mkey' <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
437− mkey' `shouldEqual` none
441− it "getAllKeys()" do
443− { storeParams: IDBDatabase.defaultParameters
444− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
445− key1 <- IDBObjectStore.add store "patate" (Just 14)
446− key2 <- IDBObjectStore.add store "autruche" (Just 42)
447− key3 <- IDBObjectStore.add store 14 (Just 1337)
450− keys <- IDBObjectStore.getAllKeys store Nothing Nothing
451− keys `shouldEqual` [key1, key2, key3]
454− keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
455− keys' `shouldEqual` [key2, key3]
458− keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
459− keys'' `shouldEqual` [key1, key2]
462− keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
463− keys''' `shouldEqual` [key1, key2]
467− it "openCursor()" do
469− { onSuccess : const $ pure unit
470− , onError : show >>> fail >>> launchAff'
471− , onComplete: pure unit
473− { db } <- setup
438+ { db } <- setup
474− { storeParams: IDBDatabase.defaultParameters
439+ { storeParams: IDBDatabase.defaultParameters
475− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
440+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
476− _ <- IDBObjectStore.openCursor store Nothing Next cb
477− _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
441+ _ <- IDBObjectStore.add store "patate" (Just 14)
478− _ <- IDBObjectStore.openCursor store Nothing Prev cb
442+ _ <- IDBObjectStore.add store "autruche" (Just 42)
479− _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
443+ n <- IDBObjectStore.count store Nothing
480− _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
444+ n `shouldEqual` 2
485− it "openKeyCursor()" do
487− { onSuccess : const $ pure unit
488− , onError : show >>> fail >>> launchAff'
489− , onComplete: pure unit
491− { db } <- setup
446+ tearDown db
492− { storeParams: IDBDatabase.defaultParameters
447+
493− , onUpgradeNeeded: Just $ \_ store -> launchAff' do
448+ it "getKey()" do
494− _ <- IDBObjectStore.openKeyCursor store Nothing Next cb
449+ { db } <- setup
495− _ <- IDBObjectStore.openKeyCursor store Nothing NextUnique cb
450+ { storeParams: IDBDatabase.defaultParameters
496− _ <- IDBObjectStore.openKeyCursor store Nothing Prev cb
451+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
497− _ <- IDBObjectStore.openKeyCursor store Nothing PrevUnique cb
452+ key <- IDBObjectStore.add store "patate" (Just 14)
498− _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
453+ mkey <- IDBObjectStore.getKey store (IDBKeyRange.only 14)
454+ mkey `shouldEqual` (Just key)
456+ mkey' <- IDBObjectStore.getKey store (IDBKeyRange.only 42)
457+ mkey' `shouldEqual` none
461+ it "getAllKeys()" do
463+ { storeParams: IDBDatabase.defaultParameters
464+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
465+ key1 <- IDBObjectStore.add store "patate" (Just 14)
466+ key2 <- IDBObjectStore.add store "autruche" (Just 42)
467+ key3 <- IDBObjectStore.add store 14 (Just 1337)
470+ keys <- IDBObjectStore.getAllKeys store Nothing Nothing
471+ keys `shouldEqual` [ key1, key2, key3 ]
474+ keys' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 14 true) Nothing
475+ keys' `shouldEqual` [ key2, key3 ]
478+ keys'' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.upperBound 42 false) Nothing
479+ keys'' `shouldEqual` [ key1, key2 ]
482+ keys''' <- IDBObjectStore.getAllKeys store (Just $ IDBKeyRange.lowerBound 1 true) (Just 2)
483+ keys''' `shouldEqual` [ key1, key2 ]
487+ it "openCursor()" do
490+ { onSuccess: const $ pure unit
491+ , onError: show >>> fail >>> launchAff'
492+ , onComplete: pure unit
495+ { storeParams: IDBDatabase.defaultParameters
496+ , onUpgradeNeeded: Just $ \_ store -> launchAff' do
497+ _ <- IDBObjectStore.openCursor store Nothing Next cb
498+ _ <- IDBObjectStore.openCursor store Nothing NextUnique cb
499+ _ <- IDBObjectStore.openCursor store Nothing Prev cb
500+ _ <- IDBObjectStore.openCursor store Nothing PrevUnique cb
501+ _ <- IDBObjectStore.openCursor store (Just $ IDBKeyRange.upperBound 1 true) Next cb
506+ it "openKeyCursor()" do
509+ { onSuccess: const $ pure unit
510+ , onError: show >>> fail >>> launchAff'
511+ , onComplete: pure unit
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
520+ _ <- IDBObjectStore.openKeyCursor store (Just $ IDBKeyRange.lowerBound 1 true) Next cb
525+ describe "IDBIndex" do
528+ IDBDatabase.close db
529+ _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
499 pure unit
530 pure unit
503− describe "IDBIndex" do
532+ setup
506− IDBDatabase.close db
507− _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
510− setup :: forall value e e'.
533+ :: forall value
511− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
534+ . { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
512− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
535+ , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
513− , values :: Array (Tuple value (Maybe Key))
536+ , values :: Array (Tuple value (Maybe Key))
514− , keyPath :: Array String
537+ , keyPath :: Array String
515− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
538+ , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Effect Unit)
516− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
540+ -> Aff { db :: Database, index :: Index, store :: ObjectStore }
517− setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
541+ setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
518− let onUpgradeNeeded' var db tx _ = launchAff' do
543+ onUpgradeNeeded' var db tx _ = launchAff' do
519 store <- IDBDatabase.createObjectStore db "store" storeParams
544 store <- IDBDatabase.createObjectStore db "store" storeParams
520− _ <- traverse (uncurry (IDBObjectStore.add store)) values
545+ _ <- traverse (uncurry (IDBObjectStore.add store)) values
521 index <- IDBObjectStore.createIndex store "index" keyPath indexParams
546 index <- IDBObjectStore.createIndex store "index" keyPath indexParams
522− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
547+ liftEffect $ maybe (pure unit) identity (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
523− putVar { db, index, store } var
548+ AVar.put { db, index, store } var
551+ _ <- IDBFactory.open "db" Nothing
552+ { onUpgradeNeeded: Just (onUpgradeNeeded' var)
553+ , onBlocked: Nothing
557+ it "returns an IDBIndex and the properties are set correctly" do
558+ { db, index } <- setup
559+ { storeParams: IDBDatabase.defaultParameters
560+ , indexParams: IDBObjectStore.defaultParameters
561+ , onUpgradeNeeded: Nothing
565+ IDBIndex.name index `shouldEqual` "index"
566+ IDBIndex.keyPath index `shouldEqual` []
567+ IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
568+ IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
571+ it "attempt to create an index that requires unique values on an object store already contains duplicates" do
572+ let onAbort var = launchAff' (AVar.put true var)
575+ res <- attempt $ setup
576+ { storeParams: IDBDatabase.defaultParameters
581+ , keyPath: [ "indexedProperty" ]
583+ [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
584+ , { indexedProperty: "bar" } :+: (Just $ toKey 2)
586+ , onUpgradeNeeded: Just $ \db tx _ -> launchAff' do
587+ IDBTransaction.onAbort tx (onAbort txVar)
588+ IDBDatabase.onAbort db (onAbort dbVar)
592+ fail "expected abort"
594+ shouldEqual true =<< AVar.take txVar
595+ shouldEqual true =<< AVar.take dbVar
597+ it "the index is usable right after being made" do
600+ { keyPath: [ "key" ]
601+ , autoIncrement: false
603+ , indexParams: IDBObjectStore.defaultParameters
604+ , keyPath: [ "indexedProperty" ]
606+ [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
607+ , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
608+ , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
610+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
611+ val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
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"
525− var <- makeEmptyVar
764+ tearDown db
526− db <- IDBFactory.open "db" Nothing
765+
527− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
766+ it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
528− , onBlocked : Nothing
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"
533− it "returns an IDBIndex and the properties are set correctly" do
534− { db, index } <- setup
535− { storeParams : IDBDatabase.defaultParameters
536− , indexParams : IDBObjectStore.defaultParameters
537− , onUpgradeNeeded : Nothing
541− IDBIndex.name index `shouldEqual` "index"
542− IDBIndex.keyPath index `shouldEqual` []
543− IDBIndex.unique index `shouldEqual` IDBObjectStore.defaultParameters.unique
544− IDBIndex.multiEntry index `shouldEqual` IDBObjectStore.defaultParameters.multiEntry
547− it "attempt to create an index that requires unique values on an object store already contains duplicates" do
548− let onAbort var = launchAff' (putVar true var)
549− txVar <- makeEmptyVar
550− dbVar <- makeEmptyVar
551− res <- attempt $ setup
552− { storeParams : IDBDatabase.defaultParameters
553− , indexParams : { unique : true
554− , multiEntry : false
556− , keyPath : ["indexedProperty"]
557− , values : [ { indexedProperty: "bar" } :+: (Just $ toKey 1)
558− , { indexedProperty: "bar" } :+: (Just $ toKey 2)
560− , onUpgradeNeeded : Just $ \db tx _ -> launchAff' do
561− IDBTransaction.onAbort tx (onAbort txVar)
562− IDBDatabase.onAbort db (onAbort dbVar)
564− case res of
789+ case res of
566− fail "expected abort"
790+ Right _ -> fail "expected InvalidStateError"
568− shouldEqual true =<< takeVar txVar
569− shouldEqual true =<< takeVar dbVar
572− it "the index is usable right after being made" do
574− { storeParams : { keyPath : ["key"]
575− , autoIncrement : false
577− , indexParams : IDBObjectStore.defaultParameters
578− , keyPath : ["indexedProperty"]
579− , values : [ { key: "key1", indexedProperty: "indexed_1" } :+: Nothing
580− , { key: "key2", indexedProperty: "indexed_2" } :+: Nothing
581− , { key: "key3", indexedProperty: "indexed_3" } :+: Nothing
583− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
584− val <- IDBIndex.get index (IDBKeyRange.only "indexed_2")
585− ((\r -> r.key) <$> val) `shouldEqual` (Just $ toKey "key2")
589− it "empty keyPath" do
591− { storeParams : IDBDatabase.defaultParameters
592− , indexParams : IDBObjectStore.defaultParameters
594− , values : [ "object_1" :+: (Just $ toKey 1)
595− , "object_2" :+: (Just $ toKey 2)
596− , "object_3" :+: (Just $ toKey 3)
598− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
599− val <- IDBIndex.get index (IDBKeyRange.only "object_3")
600− val `shouldEqual` (Just "object_3")
604− it "index can be valid keys [date]" do
605− date <- liftEff $ toDateTime <$> now
607− { storeParams : { keyPath: ["key"]
608− , autoIncrement: false
610− , indexParams : IDBObjectStore.defaultParameters
612− , values : [ { key: "date", i: (toKey date) } :+: Nothing
614− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
615− val <- IDBIndex.get index (IDBKeyRange.only date)
616− ((\r -> r.key) <$> val) `shouldEqual` (Just "date")
620− it "index can be valid keys [num]" do
623− { storeParams : { keyPath: ["key"]
624− , autoIncrement: false
626− , indexParams : IDBObjectStore.defaultParameters
628− , values : [ { key: "num", i: (toKey num) } :+: Nothing
630− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
631− val <- IDBIndex.get index (IDBKeyRange.only num)
632− ((\r -> r.key) <$> val) `shouldEqual` (Just "num")
636− it "index can be valid keys [array]" do
637− let array = ["patate", "autruche"]
639− { storeParams : { keyPath: ["key"]
640− , autoIncrement: false
642− , indexParams : IDBObjectStore.defaultParameters
644− , values : [ { key: "array", i: (toKey array) } :+: Nothing
646− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
647− val <- IDBIndex.get index (IDBKeyRange.only array)
648− ((\r -> r.key) <$> val) `shouldEqual` (Just "array")
652− it "openKeyCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
653− res <- attempt $ setup
654− { storeParams : { keyPath: ["key"], autoIncrement: false }
655− , indexParams : IDBObjectStore.defaultParameters
656− , keyPath : ["indexedProperty"]
657− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
659− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
661− { onSuccess : const $ pure unit
791+ _ -> pure unit
662− , onError : show >>> fail >>> launchAff'
792+
663− , onComplete: pure unit
665− IDBTransaction.onAbort tx (pure unit)
666− IDBDatabase.onAbort db (pure unit)
667− IDBTransaction.abort tx
668− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
670− Right _ -> fail "expected InvalidStateError"
671− Left err -> name err `shouldEqual` "InvalidStateError"
674− Right _ -> fail "expected InvalidStateError"
677− it "openKeyCursor() - throw TransactionInactiveError on aborted transaction" do
793+ it "openCursor() - throw TransactionInactiveError on aborted transaction" do
678− { db } <- setup
794+ { db } <- setup
679− { storeParams : { keyPath: ["key"], autoIncrement: false }
795+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
680− , indexParams : IDBObjectStore.defaultParameters
796+ , indexParams: IDBObjectStore.defaultParameters
681− , keyPath : ["indexedProperty"]
797+ , keyPath: [ "indexedProperty" ]
682− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
799+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
684− , onUpgradeNeeded : Nothing
801+ , onUpgradeNeeded: Nothing
687− { onSuccess : const $ pure unit
688− , onError : show >>> fail >>> launchAff'
689− , onComplete: pure unit
805+ { onSuccess: const $ pure unit
806+ , onError: show >>> fail >>> launchAff'
807+ , onComplete: pure unit
691− tx <- IDBDatabase.transaction db ["store"] ReadOnly
809+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
692− store <- IDBTransaction.objectStore tx "store"
810+ store <- IDBTransaction.objectStore tx "store"
693− index <- IDBObjectStore.index store "index"
811+ index <- IDBObjectStore.index store "index"
694− IDBTransaction.onAbort tx (pure unit)
812+ IDBTransaction.onAbort tx (pure unit)
695− IDBTransaction.abort tx
813+ IDBTransaction.abort tx
696− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
814+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
697− case cursor of
815+ case cursor of
698− Right _ -> fail "expected TransactionInactiveError"
816+ Right _ -> fail "expected TransactionInactiveError"
699− Left err -> name err `shouldEqual` "TransactionInactiveError"
817+ Left err -> name err `shouldEqual` "TransactionInactiveError"
701− tearDown db
819+ tearDown db
703− it "openKeyCursor() - throw InvalidStateError when the index is deleted" do
821+ it "openCursor() - throw InvalidStateError when the index is deleted" do
704− { db } <- setup
822+ { db } <- setup
705− { storeParams : { keyPath: ["key"], autoIncrement: false }
823+ { storeParams: { keyPath: [ "key" ], autoIncrement: false }
706− , indexParams : IDBObjectStore.defaultParameters
824+ , indexParams: IDBObjectStore.defaultParameters
707− , keyPath : ["indexedProperty"]
825+ , keyPath: [ "indexedProperty" ]
708− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
827+ [ { key: 14, indexedProperty: "patate" } :+: Nothing
710− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
829+ , onUpgradeNeeded: Just $ \db tx index -> launchAff' do
712− { onSuccess : const $ pure unit
832+ { onSuccess: const $ pure unit
713− , onError : show >>> fail >>> launchAff'
833+ , onError: show >>> fail >>> launchAff'
714− , onComplete: pure unit
834+ , onComplete: pure unit
716− store <- IDBTransaction.objectStore tx "store"
836+ store <- IDBTransaction.objectStore tx "store"
717− IDBObjectStore.deleteIndex store "index"
837+ IDBObjectStore.deleteIndex store "index"
718− cursor <- attempt $ IDBIndex.openKeyCursor index Nothing Next cb
838+ cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
719− case cursor of
839+ case cursor of
720− Right _ -> fail "expected InvalidStateError"
840+ Right _ -> fail "expected InvalidStateError"
721− Left err -> name err `shouldEqual` "InvalidStateError"
726− it "openCursor() - throw InvalidStateError on index deleted by aborted upgrade" do
727− res <- attempt $ setup
728− { storeParams : { keyPath: ["key"], autoIncrement: false }
729− , indexParams : IDBObjectStore.defaultParameters
730− , keyPath : ["indexedProperty"]
731− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
733− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
735− { onSuccess : const $ pure unit
736− , onError : show >>> fail >>> launchAff'
737− , onComplete: pure unit
739− IDBTransaction.onAbort tx (pure unit)
740− IDBDatabase.onAbort db (pure unit)
741− IDBTransaction.abort tx
742− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
744− Right _ -> fail "expected InvalidStateError"
745− Left err -> name err `shouldEqual` "InvalidStateError"
841+ Left err -> name err `shouldEqual` "InvalidStateError"
748− Right _ -> fail "expected InvalidStateError"
751− it "openCursor() - throw TransactionInactiveError on aborted transaction" do
753− { storeParams : { keyPath: ["key"], autoIncrement: false }
754− , indexParams : IDBObjectStore.defaultParameters
755− , keyPath : ["indexedProperty"]
756− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
758− , onUpgradeNeeded : Nothing
761− { onSuccess : const $ pure unit
762− , onError : show >>> fail >>> launchAff'
763− , onComplete: pure unit
765− tx <- IDBDatabase.transaction db ["store"] ReadOnly
766− store <- IDBTransaction.objectStore tx "store"
767− index <- IDBObjectStore.index store "index"
768− IDBTransaction.onAbort tx (pure unit)
769− IDBTransaction.abort tx
770− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
772− Right _ -> fail "expected TransactionInactiveError"
773− Left err -> name err `shouldEqual` "TransactionInactiveError"
777− it "openCursor() - throw InvalidStateError when the index is deleted" do
779− { storeParams : { keyPath: ["key"], autoIncrement: false }
780− , indexParams : IDBObjectStore.defaultParameters
781− , keyPath : ["indexedProperty"]
782− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
784− , onUpgradeNeeded : Just $ \db tx index -> launchAff' do
786− { onSuccess : const $ pure unit
787− , onError : show >>> fail >>> launchAff'
788− , onComplete: pure unit
790− store <- IDBTransaction.objectStore tx "store"
791− IDBObjectStore.deleteIndex store "index"
792− cursor <- attempt $ IDBIndex.openCursor index Nothing Next cb
794− Right _ -> fail "expected InvalidStateError"
795− Left err -> name err `shouldEqual` "InvalidStateError"
800− it "getKey() - multiEntry - adding keys" do
802− { storeParams : IDBDatabase.defaultParameters
803− , indexParams : { unique: false, multiEntry: true }
804− , keyPath : ["name"]
805− , values : [ { name: ["patate", "autruche"] } :+: (Just $ toKey 1)
806− , { name: ["bob"] } :+: (Just $ toKey 2)
808− , onUpgradeNeeded : Just $ \_ _ index -> launchAff' do
809− key <- IDBIndex.getKey index (IDBKeyRange.only "patate")
810− key `shouldEqual` (Just $ toKey 1)
812− key' <- IDBIndex.getKey index (IDBKeyRange.only "autruche")
813− key' `shouldEqual` (Just $ toKey 1)
815− key'' <- IDBIndex.getKey index (IDBKeyRange.only "bob")
816− key'' `shouldEqual` (Just $ toKey 2)
821− it "get() - returns the record with the first key in the range" do
823− { storeParams : { keyPath: ["key"], autoIncrement: false }
824− , indexParams : IDBObjectStore.defaultParameters
825− , keyPath : ["indexedProperty"]
826− , values : [ { key: 14, indexedProperty: "patate" } :+: Nothing
827− , { key: 42, indexedProperty: "autruche" } :+: Nothing
828− , { key: 1337, indexedProperty: "baguette" } :+: Nothing
830− , onUpgradeNeeded : Nothing
833− tx <- IDBDatabase.transaction db ["store"] ReadOnly
834− store <- IDBTransaction.objectStore tx "store"
835− index <- IDBObjectStore.index store "index"
836− val <- IDBIndex.get index (IDBKeyRange.lowerBound "autruche" false)
837− ((\r -> r.key) <$> val) `shouldEqual` (Just 42)
841− describe "IDBCursor" do
844− IDBDatabase.close db
845− _ <- IDBFactory.deleteDatabase (IDBDatabase.name db)
848− setup :: forall value e e'.
849− { storeParams :: { keyPath :: Array String, autoIncrement :: Boolean }
850− , indexParams :: { unique :: Boolean, multiEntry :: Boolean }
851− , values :: Array (Tuple value (Maybe Key))
852− , keyPath :: Array String
853− , onUpgradeNeeded :: Maybe (Database -> Transaction -> Index -> Eff (idb :: IDB, avar :: AVAR, exception :: EXCEPTION | e') Unit)
854− } -> Aff (idb :: IDB, avar :: AVAR | e) { db :: Database, index :: Index, store :: ObjectStore }
855− setup { storeParams, indexParams, values, keyPath, onUpgradeNeeded } = do
856− let onUpgradeNeeded' var db tx _ = launchAff' do
857− store <- IDBDatabase.createObjectStore db "store" storeParams
858− _ <- traverse (uncurry (IDBObjectStore.add store)) values
859− index <- IDBObjectStore.createIndex store "index" keyPath indexParams
860− liftEff $ maybe (pure unit) id (onUpgradeNeeded <*> pure db <*> pure tx <*> pure index)
861− putVar { db, index, store } var
863− var <- makeEmptyVar
844+ tearDown db
864− db <- IDBFactory.open "db" Nothing
845+
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)
865− { onUpgradeNeeded : Just (onUpgradeNeeded' var)
855+ , onUpgradeNeeded: Just $ \_ _ index -> launchAff' do
866− , onBlocked : Nothing
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
869−
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
870− it "continue() - iterate to the next record" do
920+ it "continue() - iterate to the next record" do
871− { db } <- setup
921+ { db } <- setup
872− { storeParams : IDBDatabase.defaultParameters
922+ { storeParams: IDBDatabase.defaultParameters
873− , indexParams : IDBObjectStore.defaultParameters
923+ , indexParams: IDBObjectStore.defaultParameters
874− , keyPath : []
924+ , keyPath: []
875− , values : [ "cupcake" :+: (Just $ toKey 4)
926+ [ "cupcake" :+: (Just $ toKey 4)
876− , "pancake" :+: (Just $ toKey 2)
927+ , "pancake" :+: (Just $ toKey 2)
877− , "pie" :+: (Just $ toKey 1)
928+ , "pie" :+: (Just $ toKey 1)
878− , "pie" :+: (Just $ toKey 3)
929+ , "pie" :+: (Just $ toKey 3)
880− , onUpgradeNeeded: Nothing
931+ , onUpgradeNeeded: Nothing
882− let cb vdone vvals =
883− { onComplete: launchAff' do
886− , onError: \error -> launchAff' do
887− fail $ "unexpected error: " <> show error
889− , onSuccess: \cursor -> launchAff' do
890− vals <- takeVar vvals
891− pure (IDBCursor.value cursor) >>= shouldEqual (maybe "" _.v $ head vals)
892− IDBCursor.primaryKey cursor >>= shouldEqual (maybe (toKey 0) _.k $ head vals)
893− putVar (drop 1 vals) vvals
894− IDBCursor.continue cursor none
896− vdone <- makeEmptyVar
933+ let
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
897− vvals <- makeVar
949+ vvals <- AVar.new
898− [ { v: "pie" , k: toKey 1 }
950+ [ { v: "pie", k: toKey 1 }
899− , { v: "pancake", k: toKey 2 }
951+ , { v: "pancake", k: toKey 2 }
900− , { v: "pie" , k: toKey 3 }
952+ , { v: "pie", k: toKey 3 }
901− , { v: "cupcake", k: toKey 4 }
953+ , { v: "cupcake", k: toKey 4 }
903− tx <- IDBDatabase.transaction db ["store"] ReadOnly
955+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
904− store <- IDBTransaction.objectStore tx "store"
956+ store <- IDBTransaction.objectStore tx "store"
905− IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
957+ IDBObjectStore.openCursor store Nothing Next (cb vdone vvals)
906− takeVar vdone
958+ AVar.take vdone
907− tearDown db
959+ tearDown db
909− it "continue() - attempt to iterate in the wrong direction" do
961+ it "continue() - attempt to iterate in the wrong direction" do
910− { db } <- setup
962+ { db } <- setup
911− { storeParams : IDBDatabase.defaultParameters
963+ { storeParams: IDBDatabase.defaultParameters
912− , indexParams : IDBObjectStore.defaultParameters
964+ , indexParams: IDBObjectStore.defaultParameters
913− , keyPath : []
965+ , keyPath: []
914− , values : [ "cupcake" :+: (Just $ toKey 4)
967+ [ "cupcake" :+: (Just $ toKey 4)
915− , "pancake" :+: (Just $ toKey 2)
968+ , "pancake" :+: (Just $ toKey 2)
916− , "pie" :+: (Just $ toKey 1)
969+ , "pie" :+: (Just $ toKey 1)
917− , "pie" :+: (Just $ toKey 3)
970+ , "pie" :+: (Just $ toKey 3)
919− , onUpgradeNeeded: Nothing
972+ , onUpgradeNeeded: Nothing
922− { onComplete: launchAff' do
923− fail $ "shouldn't complete"
925− , onError: \error -> launchAff' do
926− fail $ "unexpected error: " <> show error
928− , onSuccess: \cursor -> launchAff' do
929− res <- attempt $ IDBCursor.continue cursor (Just 1)
932− name err `shouldEqual` "DataError"
935− fail "expected continue to fail"
937− vdone <- makeEmptyVar
975+ cb vdone =
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"
938− tx <- IDBDatabase.transaction db ["store"] ReadOnly
992+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
939− store <- IDBTransaction.objectStore tx "store"
993+ store <- IDBTransaction.objectStore tx "store"
940− IDBObjectStore.openCursor store Nothing Next (cb vdone)
994+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
941− takeVar vdone
995+ AVar.take vdone
942− tearDown db
996+ tearDown db
945− it "advance() - iterate cursor number of times specified by count" do
998+ it "advance() - iterate cursor number of times specified by count" do
946− { db } <- setup
999+ { db } <- setup
947− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1000+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
948− , indexParams : IDBObjectStore.defaultParameters
1001+ , indexParams: IDBObjectStore.defaultParameters
949− , keyPath : []
1002+ , keyPath: []
950− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1004+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
951− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1005+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
952− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1006+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
953− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1007+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
955− , onUpgradeNeeded: Nothing
1009+ , onUpgradeNeeded: Nothing
957− let cb vdone vjump =
958− { onComplete: launchAff' do
961− , onError: \error -> launchAff' do
962− fail $ "unexpected error: " <> show error
964− , onSuccess: \cursor -> launchAff' do
965− jump <- takeVar vjump
968− IDBCursor.advance cursor 3
970− let value = IDBCursor.value cursor
971− value.pKey `shouldEqual` "pkey_3"
972− value.iKey `shouldEqual` "ikey_3"
973− IDBCursor.continue cursor none
976− vdone <- makeEmptyVar
1011+ let
977− vjump <- makeVar true
1012+ cb vdone vjump =
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
978− tx <- IDBDatabase.transaction db ["store"] ReadOnly
1032+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
979− store <- IDBTransaction.objectStore tx "store"
1033+ store <- IDBTransaction.objectStore tx "store"
980− IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
1034+ IDBObjectStore.openCursor store Nothing Next (cb vdone vjump)
981− takeVar vdone
1035+ AVar.take vdone
982− tearDown db
1036+ tearDown db
984− it "delete() - remove a record from the object store" do
1038+ it "delete() - remove a record from the object store" do
985− { db } <- setup
1039+ { db } <- setup
986− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1040+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
987− , indexParams : IDBObjectStore.defaultParameters
1041+ , indexParams: IDBObjectStore.defaultParameters
988− , keyPath : []
1042+ , keyPath: []
989− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1044+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
990− , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
1045+ , { pKey: "pkey_1", iKey: "ikey_1" } :+: Nothing
991− , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
1046+ , { pKey: "pkey_2", iKey: "ikey_2" } :+: Nothing
992− , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
1047+ , { pKey: "pkey_3", iKey: "ikey_3" } :+: Nothing
994− , onUpgradeNeeded: Nothing
1049+ , onUpgradeNeeded: Nothing
996− let cb vdone store =
997− { onComplete: launchAff' do
998− mval <- map _.pKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
999− mval `shouldEqual` (Nothing :: Maybe String)
1002− , onError: \error -> launchAff' do
1003− fail $ "unexpected error: " <> show error
1005− , onSuccess: \cursor -> launchAff' do
1006− let value = IDBCursor.value cursor
1007− value.pKey `shouldEqual` "pkey_0"
1008− IDBCursor.delete cursor
1009− IDBCursor.advance cursor 4
1011− vdone <- makeEmptyVar
1051+ let
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
1012− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1068+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1013− store <- IDBTransaction.objectStore tx "store"
1069+ store <- IDBTransaction.objectStore tx "store"
1014− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1070+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1015− takeVar vdone
1071+ AVar.take vdone
1016− tearDown db
1072+ tearDown db
1018− it "update() - modify a record in the object store" do
1074+ it "update() - modify a record in the object store" do
1019− { db } <- setup
1075+ { db } <- setup
1020− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1076+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1021− , indexParams : IDBObjectStore.defaultParameters
1077+ , indexParams: IDBObjectStore.defaultParameters
1022− , keyPath : []
1078+ , keyPath: []
1023− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1080+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1025− , onUpgradeNeeded: Nothing
1082+ , onUpgradeNeeded: Nothing
1027− let cb vdone store =
1028− { onComplete: launchAff' do
1029− mval <- map _.iKey <$> IDBIndex.get store (IDBKeyRange.only "pkey_0")
1030− mval `shouldEqual` (Just "patate")
1033− , onError: \error -> launchAff' do
1034− fail $ "unexpected error: " <> show error
1036− , onSuccess: \cursor -> launchAff' do
1037− let value = IDBCursor.value cursor
1038− value.pKey `shouldEqual` "pkey_0"
1039− key <- IDBCursor.update cursor { pKey: "pkey_0", iKey: "patate" }
1040− key `shouldEqual` toKey "pkey_0"
1041− IDBCursor.advance cursor 4
1043− vdone <- makeEmptyVar
1084+ let
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
1044− tx <- IDBDatabase.transaction db ["store"] ReadWrite
1102+ tx <- IDBDatabase.transaction db [ "store" ] ReadWrite
1045− store <- IDBTransaction.objectStore tx "store"
1103+ store <- IDBTransaction.objectStore tx "store"
1046− IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1104+ IDBObjectStore.openCursor store Nothing Next (cb vdone store)
1047− takeVar vdone
1105+ AVar.take vdone
1048− tearDown db
1106+ tearDown db
1050− it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1108+ it "update() - throw ReadOnlyError after update on ReadOnly transaction" do
1051− { db } <- setup
1109+ { db } <- setup
1052− { storeParams : { keyPath: ["pKey"], autoIncrement: false }
1110+ { storeParams: { keyPath: [ "pKey" ], autoIncrement: false }
1053− , indexParams : IDBObjectStore.defaultParameters
1111+ , indexParams: IDBObjectStore.defaultParameters
1054− , keyPath : []
1112+ , keyPath: []
1055− , values : [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1114+ [ { pKey: "pkey_0", iKey: "ikey_0" } :+: Nothing
1057− , onUpgradeNeeded: Nothing
1116+ , onUpgradeNeeded: Nothing
1060− { onComplete: launchAff' do
1061− fail $ "shouldn't complete"
1063− , onError: \error -> launchAff' do
1064− fail $ "unexpected error: " <> show error
1066− , onSuccess: \cursor -> launchAff' do
1067− res <- attempt $ IDBCursor.update cursor "patate"
1070− name err `shouldEqual` "ReadOnlyError"
1073− fail $ "expected ReadOnlyError"
1075− vdone <- makeEmptyVar
1119+ cb vdone =
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
1076− tx <- IDBDatabase.transaction db ["store"] ReadOnly
1136+ tx <- IDBDatabase.transaction db [ "store" ] ReadOnly
1077− store <- IDBTransaction.objectStore tx "store"
1137+ store <- IDBTransaction.objectStore tx "store"
1078− IDBObjectStore.openCursor store Nothing Next (cb vdone)
1138+ IDBObjectStore.openCursor store Nothing Next (cb vdone)
1079− takeVar vdone
1139+ AVar.take vdone
1080− tearDown db
1140+ tearDown db