const abstractTests = require('abstract-chunk-store/tests')
const CacheChunkStore = require('../')
const FSChunkStore = require('fs-chunk-store')
const ImmediateChunkStore = require('immediate-chunk-store')
const MemoryChunkStore = require('memory-chunk-store')
const test = require('tape')

abstractTests(test, function (chunkLength) {
  return new CacheChunkStore(new FSChunkStore(chunkLength))
})

abstractTests(test, function (chunkLength) {
  return new CacheChunkStore(new MemoryChunkStore(chunkLength))
})

abstractTests(test, function (chunkLength) {
  return new CacheChunkStore(new ImmediateChunkStore(new FSChunkStore(chunkLength)))
})

test('fs-chunk-store: get should be cached', t => {
  runTest(t, FSChunkStore)
})

test('memory-chunk-store: get should be cached', t => {
  runTest(t, MemoryChunkStore)
})

test('immediate-chunk-store: fs-chunk-store: get should be cached', t => {
  runTest(t, function (chunkLength) {
    return new ImmediateChunkStore(new FSChunkStore(chunkLength))
  })
})

function runTest (t, Store) {
  const fsStore = new Store(10)
  const store = new CacheChunkStore(fsStore, { max: 10 })

  store.put(0, Buffer.from('0123456789'), err => {
    t.error(err)
    store.get(0, (err, data) => {
      t.error(err)
      t.deepEqual(data, Buffer.from('0123456789'))

      fsStore.get = () => {
        t.fail('get should be cached - not called on underlying store')
      }

      store.get(0, (err, data) => {
        t.error(err)
        t.deepEqual(data, Buffer.from('0123456789'))

        store.destroy(err => {
          t.error(err)
          t.end()
        })
      })
    })
  })
}

@@ -289,230 +289,83 @@
 ')%0A%0A
-abstractTests(test, function (chunkLength) %7B%0A  return new CacheChunkStore(new FSChunkStore(chunkLength))%0A%7D)%0A%0AabstractTests(test, function (chunkLength) %7B%0A  return new CacheChunkStore(new MemoryChunkStore(chunkLength))%0A%7D)%0A%0A
+test('abstract-chunk-store tests', t =%3E %7B%0A  testAllStores(t, (Store, t) =%3E 
 abst
@@ -378,379 +378,109 @@
 sts(
+t.
 test
-, function (chunkLength) %7B%0A  return new CacheChunkStore(new ImmediateChunkStore(new FSChunkStore(chunkLength)))%0A%7D)%0A%0Atest('fs-chunk-store: get should be cached', t =%3E %7B%0A  runTest(t, FSChunkStore)%0A%7D)%0A%0Atest('memory-chunk-store: get should be cached', t =%3E %7B%0A  runTest(t, MemoryChunkStore)%0A%7D)%0A%0Atest('immediate-chunk-store: fs-chunk-store: get should be cached'
+.bind(t), Store))%0A%7D)%0A%0Atest('get should be cached', t =%3E %7B%0A  testAllStores(t, (Store
 , t
+)
  =%3E %7B%0A  
 runT
@@ -479,159 +479,39 @@
 %7B%0A  
-runTest(t, function (chunkLength) %7B%0A    return new ImmediateChunkStore(new FSChunkStore(chunkLength))%0A  %7D)%0A%7D)%0A%0Afunction runTest (t, Store) %7B%0A  const fs
+  t.plan(6)%0A%0A    const original
 Stor
@@ -530,16 +530,18 @@
 e(10)%0A  
+ 
+ 
 const st
@@ -566,18 +566,24 @@
 nkStore(
-fs
+original
 Store, %7B
@@ -595,16 +595,18 @@
  10 %7D)%0A%0A
+  
   store.
@@ -648,24 +648,26 @@
 rr =%3E %7B%0A    
+ 
+ 
 t.error(err)
@@ -663,24 +663,26 @@
 .error(err)%0A
+  
     store.ge
@@ -701,32 +701,34 @@
 ata) =%3E %7B%0A      
+ 
+ 
 t.error(err)%0A   
@@ -720,24 +720,26 @@
 .error(err)%0A
+  
       t.deep
@@ -784,18 +784,26 @@
 %0A%0A      
-fs
+  original
 Store.ge
@@ -810,24 +810,26 @@
 t = () =%3E %7B%0A
+  
         t.fa
@@ -888,16 +888,18 @@
 store')%0A
+  
       %7D%0A
@@ -901,24 +901,26 @@
    %7D%0A%0A      
+  
 store.get(0,
@@ -937,32 +937,34 @@
 a) =%3E %7B%0A        
+  
 t.error(err)%0A   
@@ -960,32 +960,34 @@
 or(err)%0A        
+ 
+ 
 t.deepEqual(data
@@ -1020,24 +1020,26 @@
 ))%0A%0A        
+  
 store.destro
@@ -1051,32 +1051,34 @@
  =%3E %7B%0A          
+ 
+ 
 t.error(err)%0A   
@@ -1088,46 +1088,534 @@
     
-t.end()%0A        %7D)%0A      %7D)%0A    %7D)%0A  %7D)
+%7D)%0A        %7D)%0A      %7D)%0A    %7D)%0A  %7D)%0A%7D)%0A%0Afunction testAllStores (t, testFn) %7B%0A  const allStores = %5B%0A    %7B name: 'fs-chunk-store', Store: FSChunkStore %7D,%0A    %7B name: 'memory-chunk-store', Store: MemoryChunkStore %7D,%0A    %7B%0A      name: 'immediate-chunk-store',%0A      Store: function (chunkLength) %7B%0A        return new ImmediateChunkStore(new FSChunkStore(chunkLength))%0A      %7D%0A    %7D%0A  %5D%0A%0A  // Run the same test on all three stores%0A  for (const %7B name, Store %7D of allStores) %7B%0A    t.test(name, t =%3E %7B%0A      testFn(Store, t)%0A    %7D)%0A  %7D
 %0A%7D%0A

Restructure tests