yxdb-utils 0.1.0.0 → 0.1.0.1
raw patch · 12 files changed
+580/−2 lines, 12 filesbinary-added
Files
- Tests/Codec/Compression/LZF/ByteString.hs +57/−0
- Tests/Data/Binary/C.hs +30/−0
- Tests/Database/Alteryx.hs +282/−0
- Tests/Database/Alteryx/Arbitrary.hs +170/−0
- Tests/Database/Utils.hs +19/−0
- test-data/date-format.csv +2/−0
- test-data/quote-parsing.csv +3/−0
- test-data/samples.csv +2/−0
- test-data/samples_of_various_field_types.yxdb binary
- test-data/samples_without_header.csv +1/−0
- test-data/signed.csv +2/−0
- yxdb-utils.cabal +12/−2
+ Tests/Codec/Compression/LZF/ByteString.hs view
@@ -0,0 +1,57 @@+module Tests.Codec.Compression.LZF.ByteString (lzfByteStringTests) where++import Codec.Compression.LZF.ByteString+ (+ compressByteString,+ compressLazyByteString,+ decompressByteString,+ decompressByteStringFixed,+ decompressLazyByteString+ )++import Control.Applicative((<$>))++import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL++import Test.Framework+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck+import Test.QuickCheck.Instances+import Test.QuickCheck.Monadic (assert, monadic, run)++_compare :: Eq t => (t -> t) -> (t -> t) -> t -> Property+_compare a b x = property $ x == (a $ b x)++prop_DecompressCompressInverses :: BS.ByteString -> Property+prop_DecompressCompressInverses x =+ _compare decompressByteString compressByteString x++prop_LazyDecompressCompressInverses :: BSL.ByteString -> Property+prop_LazyDecompressCompressInverses x =+ _compare decompressLazyByteString compressLazyByteString x++data NSmall = NSmall Int deriving (Show)+data BSSmall = BSSmall BS.ByteString deriving (Show)++instance Arbitrary NSmall where+ arbitrary = NSmall <$> choose (0,10000)++instance Arbitrary BSSmall where+ arbitrary = do+ size <- choose(0,10000)+ BSSmall <$> BS.pack <$> vector size++prop_DecompressingAnyGarbageDoesntCauseACrash :: NSmall -> BSSmall -> Property+prop_DecompressingAnyGarbageDoesntCauseACrash (NSmall n) (BSSmall bs) =+ property $+ case decompressByteStringFixed n bs of+ Nothing -> True+ Just x -> BS.length x >= 0++lzfByteStringTests =+ testGroup "Codec.Compression.LZF.ByteString" [+ testProperty "Decompress and compress inverses" prop_DecompressCompressInverses,+ testProperty "Lazy Decompress and compress inverses" prop_LazyDecompressCompressInverses,+ testProperty "Checking for crashes on arbitrary ByteStrings" prop_DecompressingAnyGarbageDoesntCauseACrash+ ]
+ Tests/Data/Binary/C.hs view
@@ -0,0 +1,30 @@+module Tests.Data.Binary.C (cBinaryTests) where++import Control.Applicative+import Data.Binary+import Data.Binary.C+import Foreign.C.Types+import GHC.Prim (coerce)+import Test.Framework+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck+import Test.QuickCheck.Instances+import Test.QuickCheck.Monadic (assert, monadic, run)++prop_CFloat :: CFloat -> Property+prop_CFloat x = property $ (decode $ encode x) == x++prop_CDouble :: CDouble -> Property+prop_CDouble x = property $ (decode $ encode x) == x++instance Arbitrary CFloat where+ arbitrary = realToFrac <$> (arbitrary :: Gen Float)++instance Arbitrary CDouble where+ arbitrary = realToFrac <$> (arbitrary :: Gen Double)++cBinaryTests =+ testGroup "Binary instances for C types" [+ testProperty "CFloat" prop_CFloat,+ testProperty "CDouble" prop_CDouble+ ]
+ Tests/Database/Alteryx.hs view
@@ -0,0 +1,282 @@+{-# LANGUAGE OverloadedStrings #-}++module Tests.Database.Alteryx (yxdbTests) where++import qualified Database.Alteryx.CLI.Csv2Yxdb as C2Y+import qualified Database.Alteryx.CLI.Yxdb2Csv as Y2C+import Database.Alteryx+import Tests.Database.Alteryx.Arbitrary+import Tests.Database.Utils++import Prelude hiding (readFile)++import Control.Applicative+import Control.Lens hiding (elements)+import Control.Monad (replicateM, when)+import Control.Monad.State (evalStateT)+import Control.Monad.Trans.Resource+import Data.Array.IArray (listArray)+import Data.Binary+import Data.Binary.Get (runGet)+import Data.Binary.Put (runPut)+import Data.ByteString as BS+import Data.ByteString.Char8 as BSC+import Data.ByteString.Lazy as BSL+import Data.Conduit+import Data.Conduit.Combinators+import Data.Conduit.Lift+import Data.Conduit.List as CL+import qualified Data.Conduit.Text as CT+import qualified Data.CSV.Conduit as CSVT+import Data.Text as T+import Data.Text.Encoding as T+import Data.Text.IO as T++import Test.Framework+import Test.Framework.Providers.HUnit (testCase)+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.HUnit+import Test.QuickCheck++assertEq :: (Eq a, Show a) => a -> a -> Property+assertEq a b = let+ aStr = show a+ bStr = show b+ in printTestCase ("\nA: " ++ aStr ++ "\nB: " ++ bStr) (a == b)++numBytes :: Binary a => a -> Int+numBytes x = fromIntegral $ BSL.length $ runPut $ put x++prop_HeaderLength :: Header -> Property+prop_HeaderLength header =+ assertEq headerPageSize (numBytes header)++prop_MetadataLength :: YxdbFile -> Property+prop_MetadataLength yxdb =+ assertEq (numMetadataBytesHeader $ yxdb ^. yxdbFileHeader)+ (numMetadataBytesActual $ yxdb ^. yxdbFileMetadata)++-- prop_BlocksLength :: YxdbFile -> Property+-- prop_BlocksLength yxdb =+-- assertEq (numBlocksBytesHeader $ header yxdb) (numBlocksBytesActual $ blocks yxdb)++prop_ValueGetAndPutAreInverses :: PairedValue -> Property+prop_ValueGetAndPutAreInverses (PairedValue field value) =+ assertEq (runGet (getValue field) (runPut $ putValue field value)) value++prop_BlockIndexGetAndPutAreInverses :: BlockIndex -> Property+prop_BlockIndexGetAndPutAreInverses x = assertEq (decode $ encode x) x++prop_MetadataGetAndPutAreInverses :: RecordInfo -> Property+prop_MetadataGetAndPutAreInverses x = assertEq (decode $ encode x) x++prop_HeaderGetAndPutAreInverses :: Header -> Property+prop_HeaderGetAndPutAreInverses x = assertEq (decode $ encode x) x++prop_BlocksGetAndPutAreInverses :: Block -> Property+prop_BlocksGetAndPutAreInverses x = assertEq (decode $ encode x) x++prop_YxdbFileGetAndPutAreInverses :: YxdbFile -> Property+prop_YxdbFileGetAndPutAreInverses x = assertEq (decode $ encode x) x++test_LoadingSmallModule :: Assertion+test_LoadingSmallModule = do+ parsed <- decodeFileOrFail "test-data/samples_of_various_field_types.yxdb"+ case parsed of+ Left (bytes, msg) -> assertFailure (msg ++ " at " ++ show bytes ++ " bytes")+ Right yxdbFile -> const (return ()) (yxdbFile :: YxdbFile)++csv2yxdb2csv :: C2Y.Settings -> FilePath -> FilePath -> IO T.Text+csv2yxdb2csv settings inputFilename outputFilename = do+ let c2ySettings = settings & C2Y.settingFilename .~ inputFilename+ & C2Y.settingOutput .~ outputFilename+ let y2cSettings = Y2C.defaultSettings & Y2C.settingFilename .~ outputFilename+ evalStateT C2Y.runCsv2Yxdb c2ySettings+ newCsv <- T.decodeUtf8 <$> (captureStdout $ evalStateT Y2C.runYxdb2Csv y2cSettings)++ return newCsv++readCsvRecords :: Maybe Text -> FilePath -> IO [Record]+readCsvRecords header filename =+ runResourceT $+ sourceCsvRecords filename header alteryxCsvSettings $$+ sinkList++test_csv2yxdb2csvIsIdentity :: Assertion+test_csv2yxdb2csvIsIdentity = do+ let inputFilename = "test-data/samples.csv"+ let outputFilename = "test-data/samples.yxdb"+ newCsv <- csv2yxdb2csv C2Y.defaultSettings inputFilename outputFilename+ originalCsv <- T.readFile inputFilename+ assertEqual "CSV to YXDB to CSV" originalCsv newCsv++test_csv2yxdbQuoteParsing :: Assertion+test_csv2yxdbQuoteParsing = do+ let inputFilename = "test-data/quote-parsing.csv"+ let outputFilename = "test-data/quote-parsing.yxdb"+ oldCsv <- T.readFile inputFilename+ newCsv <- csv2yxdb2csv C2Y.defaultSettings inputFilename outputFilename+ assertEqual "" oldCsv newCsv++test_csv2yxdbDateFormat :: Assertion+test_csv2yxdbDateFormat = do+ let inputFilename = "test-data/date-format.csv"+ outputFilename = "test-data/date-format.yxdb"+ oldCsv <- T.readFile inputFilename+ newCsv <- csv2yxdb2csv C2Y.defaultSettings inputFilename outputFilename+ assertEqual "" oldCsv newCsv++nonAnsiCodepointFieldValue :: Maybe FieldValue+nonAnsiCodepointFieldValue = Just $ FVString "plátano"++nonAnsiCodepointField :: Field+nonAnsiCodepointField = Field {+ _fieldName = "derp",+ _fieldType = FTString,+ _fieldSize = Just 10,+ _fieldScale = Nothing+ }++test_renderNonAnsiCodepoint :: Assertion+test_renderNonAnsiCodepoint = do+ let fieldValue = nonAnsiCodepointFieldValue+ field = nonAnsiCodepointField+ bs = runPut (putValue field fieldValue)+ parsedValue = runGet (getValue field) bs+ assertEqual "Converting a non-ANSI character lost information" fieldValue parsedValue++test_renderNonAnsiCodepointRecord :: Assertion+test_renderNonAnsiCodepointRecord = do+ let fieldValue = nonAnsiCodepointFieldValue+ field = nonAnsiCodepointField++ record = Record [ fieldValue ]+ recordInfo = RecordInfo [ field ]++ record2recordConduit = record2csv recordInfo =$=+ csv2bytes =$=+ CT.decode CT.utf8 =$=+ csv2records alteryxCsvSettings+ newRecords <- runResourceT $ CL.sourceList [ record ] =$= record2recordConduit $$ sinkList++ let result = Prelude.head newRecords+ assertEqual "Converting a non-ANSI character lost information" record result++test_renderNonAnsiCodepointCSVRecord :: Assertion+test_renderNonAnsiCodepointCSVRecord =+ let csvText = "derp:string(10)\nplátano\n"+ recordInfo = RecordInfo [ nonAnsiCodepointField ]+ csv2csvConduit =+ csv2records alteryxCsvSettings =$=+ record2csv recordInfo =$=+ csv2bytes =$=+ CT.decode CT.utf8++ in do+ newCsv <- runResourceT $ CL.sourceList [ csvText ] =$= csv2csvConduit $$ sinkList+ assertEqual "" csvText $ T.concat newCsv++test_renderNonAnsiCodepointCSV2Record2Block2Record2CSV :: Assertion+test_renderNonAnsiCodepointCSV2Record2Block2Record2CSV =+ let csvText = "derp:string(10)\nplátano\n"+ recordInfo = RecordInfo [ nonAnsiCodepointField ]+ csv2csvConduit =+ csv2records alteryxCsvSettings =$=+ evalStateLC defaultStatistics (recordsToBlocks recordInfo) =$=+ blocksToRecords recordInfo =$=+ record2csv recordInfo =$=+ csv2bytes =$=+ CT.decode CT.utf8+ in do+ newCsv <- runResourceT $ CL.sourceList [ csvText ] =$= csv2csvConduit $$ sinkList+ assertEqual "" csvText $ T.concat newCsv+++test_recordParsing :: Assertion+test_recordParsing = do+ let inputFilename = "test-data/samples.csv"+ outputFilename = "test-data/samples.yxdb"+ secondOutputFilename = "test-data/samples.yxdb.csv"+ expectedRecord =+ [+ Record [+ Just (FVByte 1),+ Just (FVInt16 256),+ Just (FVInt32 32768),+ Just (FVInt64 4294967296),+ Just (FVString "1.10000"),+ Just (FVFloat 1.1),+ Just (FVDouble 1.1),+ Just (FVString "plátano"),+ Just (FVWString "香蕉"),+ Just (FVString "plátano"),+ Just (FVWString "香蕉"),+ Just (FVString "2013-12-31"),+ Just (FVString "23:34:56"),+ Just (FVString "2013-12-31 23:34:56")+ ]+ ]+ records <- readCsvRecords Nothing inputFilename+ assertEqual "Parse from CSV" expectedRecord records++ newCsv <- csv2yxdb2csv C2Y.defaultSettings inputFilename outputFilename+ yxdbFile <- decodeFile outputFilename :: IO YxdbFile++ T.writeFile secondOutputFilename newCsv+ newRecords <- readCsvRecords Nothing secondOutputFilename++ assertEqual "Parse from YXDB" expectedRecord (yxdbFile ^. yxdbFileRecords)+ assertEqual "New CSV doesn't match old" expectedRecord newRecords++test_signedRecordParsing :: Assertion+test_signedRecordParsing = do+ let inputFilename = "test-data/signed.csv"+ outputFilename = "test-data/signed.yxdb"+ secondOutputFilename = "test-data/signed.yxdb.csv"+ expectedRecord =+ [+ Record [+ Just (FVByte $ -1),+ Just (FVInt16 $ -256),+ Just (FVInt32 $ -32768),+ Just (FVInt64 $ -4294967296),+ Just (FVString "1.10000"),+ Just (FVFloat $ -1.1),+ Just (FVDouble $ -1.1)+ ]+ ]+ records <- readCsvRecords Nothing inputFilename+ assertEqual "Parse from CSV" expectedRecord records++ newCsv <- csv2yxdb2csv C2Y.defaultSettings inputFilename outputFilename+ yxdbFile <- decodeFile outputFilename :: IO YxdbFile++ T.writeFile secondOutputFilename newCsv+ newRecords <- readCsvRecords Nothing secondOutputFilename++ assertEqual "Parse from YXDB" expectedRecord (yxdbFile ^. yxdbFileRecords)+ assertEqual "New CSV doesn't match old" expectedRecord newRecords++yxdbTests :: Test.Framework.Test+yxdbTests =+ testGroup "YXDB" [+ testProperty "Header length" prop_HeaderLength,+ testProperty "Metadata length" prop_MetadataLength,+-- testProperty "Blocks length" prop_BlocksLength, --+ testProperty "Block Index get & put inverses" prop_BlockIndexGetAndPutAreInverses,+ testProperty "Metadata get and put inverses" prop_MetadataGetAndPutAreInverses,+ testProperty "Header get & put inverses" prop_HeaderGetAndPutAreInverses,+ testProperty "Value get & put inverses" prop_ValueGetAndPutAreInverses,+ testProperty "Blocks get & put inverses" prop_BlocksGetAndPutAreInverses,+-- testProperty "Yxdb get & put inverses" prop_YxdbFileGetAndPutAreInverses,+ testCase "Loading small module" test_LoadingSmallModule,+ testCase "CSV to YXDB to CSV is the identity" test_csv2yxdb2csvIsIdentity,+ testCase "Quotes are not used to escape" test_csv2yxdbQuoteParsing,+ testCase "Can parse ISO style dates" test_csv2yxdbDateFormat,+ testCase "Example CSV parses into correct structures" test_recordParsing,+ testCase "Example CSV with signed values" test_signedRecordParsing,+ testCase "Rendering a non-ANSI codepoint" test_renderNonAnsiCodepoint,+ testCase "Rendering a non-ANSI codepoint at record level" test_renderNonAnsiCodepointRecord,+ testCase "Rendering a non-ANSI codepoint from CSV to CSV" test_renderNonAnsiCodepointCSVRecord,+ testCase "Rendering a non-ANSI codepoint from CSV to YXDB blocks to CSV" test_renderNonAnsiCodepointCSV2Record2Block2Record2CSV+ ]
+ Tests/Database/Alteryx/Arbitrary.hs view
@@ -0,0 +1,170 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Tests.Database.Alteryx.Arbitrary where++import Database.Alteryx++import Conduit+import Data.Conduit.Lift as CL+import Control.Applicative+import Control.Lens hiding (elements)+import Control.Monad+import Data.Array.IArray+import Data.Binary+import Data.Binary.Put+import Data.ByteString as BS+import Data.ByteString.Lazy as BSL+import Data.Maybe+import qualified Data.Text as T+import Data.Text.Encoding+import Data.Time.Clock.POSIX+import Data.Word+import Test.QuickCheck+import Test.QuickCheck.Instances()++instance Arbitrary YxdbFile where+ arbitrary = do+ fMetadata <- arbitrary+ fBlocks <- arbitraryBlocksMatching fMetadata+ fHeader <- arbitraryHeaderMatching fMetadata fBlocks+ fBlockIndex <- arbitrary++ fRecords <- arbitraryRecordsMatching fMetadata++ return $ YxdbFile {+ _yxdbFileHeader = fHeader,+ _yxdbFileRecords = fRecords,+ _yxdbFileMetadata = fMetadata,+ _yxdbFileBlockIndex = fBlockIndex+ }++arbitraryBlocksMatching :: RecordInfo -> Gen [Block]+arbitraryBlocksMatching recordInfo = do+ records <- arbitraryRecordsMatching recordInfo+ let blocks = fromJust $ yieldMany records $= CL.evalStateLC defaultStatistics (recordsToBlocks recordInfo) $$ sinkList+ return blocks++arbitraryHeaderMatching :: RecordInfo -> [Block] -> Gen Header+arbitraryHeaderMatching metadata blocks = do+ fDescription <- replicateM 64 $ choose(0,127) :: Gen [Word8]+ fFileId <- arbitrary+ fCreationDate <- posixSecondsToUTCTime <$> fromIntegral <$> (arbitrary :: Gen Word32)+ fFlags1 <- arbitrary+ fFlags2 <- arbitrary+ fMystery <- arbitrary+ fSpatialIndexPos <- arbitrary+ let numMetadataBytes = numMetadataBytesActual metadata+ let fMetaInfoLength = fromIntegral $ numMetadataBytes `div` 2+ let numBlockBytes = sum $ Prelude.map numBlockBytesActual blocks+ let startOfBlocks = fromIntegral $ headerPageSize + (fromIntegral $ numMetadataBytes)+ let fRecordBlockIndexPos = startOfBlocks + (fromIntegral numBlockBytes)+ fNumRecords <- arbitrary+ fCompressionVersion <- arbitrary+ fReservedSpace <- vector (512 - 64 - (4 * 7) - (8 * 3)) :: Gen [Word8]+ return $ Header {+ _description = decodeUtf8 $ BS.pack $ fDescription,+ _fileId = fFileId,+ _creationDate = fCreationDate,+ _flags1 = fFlags1,+ _flags2 = fFlags2,+ _metaInfoLength = fMetaInfoLength,+ _mystery = fMystery,+ _spatialIndexPos = fSpatialIndexPos,+ _recordBlockIndexPos = fRecordBlockIndexPos,+ _numRecords = fNumRecords,+ _compressionVersion = fCompressionVersion,+ _reservedSpace = BS.pack fReservedSpace+ }++instance Arbitrary Header where+ arbitrary = do+ metadata <- arbitrary+ blocks <- arbitraryBlocksMatching metadata+ arbitraryHeaderMatching metadata blocks++arbitraryRecordsMatching :: RecordInfo -> Gen [Record]+arbitraryRecordsMatching metadata = do+ size <- choose(0,10000)+ vectorOf size (arbitraryRecordMatching metadata)++arbitraryRecordMatching :: RecordInfo -> Gen Record+arbitraryRecordMatching (RecordInfo fields) =+ Record <$> mapM arbitraryValueMatching fields++arbitraryValueMatching :: Field -> Gen (Maybe FieldValue)+arbitraryValueMatching field =+ let value =+ case field ^. fieldType of+ FTBool -> FVBool <$> arbitrary+ FTByte -> FVByte <$> arbitrary+ FTInt16 -> FVInt16 <$> arbitrary+ FTInt32 -> FVInt32 <$> arbitrary+ FTInt64 -> FVInt64 <$> arbitrary+ FTFloat -> FVFloat <$> arbitrary+ FTDouble -> FVDouble <$> arbitrary+ in do+ isNull <- arbitrary+ if isNull+ then return Nothing+ else Just <$> value++instance Arbitrary Block where+ arbitrary = Prelude.head <$> (arbitraryBlocksMatching =<< arbitrary)++instance Arbitrary FieldType where+ arbitrary = elements [+ -- FTBool,+ FTByte,+ FTInt16,+ FTInt32,+ FTInt64,+ -- FTFixedDecimal,+ FTFloat,+ FTDouble+ -- FTString,+ -- FTWString,+ -- FTVString,+ -- FTVWString,+ -- FTDate,+ -- FTTime,+ -- FTDateTime,+ -- FTBlob,+ -- FTSpatialObject,+ -- FTUnknown+ ]++instance Arbitrary Field where+ arbitrary = do+ fName <- arbitrary+ fType <- arbitrary+ fSize <- arbitrary+ fScale <- arbitrary+ return $ Field {+ _fieldName = fName,+ _fieldType = fType,+ _fieldSize = fSize,+ _fieldScale = fScale+ }++instance Arbitrary Record where+ arbitrary = arbitraryRecordMatching =<< arbitrary++instance Arbitrary RecordInfo where+ arbitrary = do+ len <- choose(1,10)+ RecordInfo <$> vector len++instance Arbitrary BlockIndex where+ arbitrary =+ sized $+ \chunkSize -> do+ indices <- replicateM chunkSize arbitrary+ return $ BlockIndex $ listArray (0, chunkSize) indices++data PairedValue = PairedValue Field (Maybe FieldValue) deriving (Eq, Show)++instance Arbitrary PairedValue where+ arbitrary = do+ field <- arbitrary+ value <- arbitraryValueMatching field+ return $ PairedValue field value
+ Tests/Database/Utils.hs view
@@ -0,0 +1,19 @@+module Tests.Database.Utils where++import Data.ByteString as BS+import GHC.IO.Handle+import System.IO+import System.Directory++captureStdout :: IO () -> IO BS.ByteString+captureStdout f = do+ tmpd <- getTemporaryDirectory+ (tmpf, tmph) <- openTempFile tmpd "haskell_stdout"+ stdout_dup <- hDuplicate stdout+ hDuplicateTo tmph stdout+ hClose tmph+ f+ hDuplicateTo stdout_dup stdout+ bs <- BS.readFile tmpf+ removeFile tmpf+ return bs
+ test-data/date-format.csv view
@@ -0,0 +1,2 @@+f1:int(16)|f2:int(16)|f3:date|f4:time|f5:datetime+500|1|2014-01-01|06:00:00|2014-0-0 06:00:00
+ test-data/quote-parsing.csv view
@@ -0,0 +1,3 @@+f1:string(7)+aoeu+"aoeu"
+ test-data/samples.csv view
@@ -0,0 +1,2 @@+f1:int(8)|f2:int(16)|f3:int(32)|f4:int(64)|f5:decimal(7,5)|f6:float|f7:double|f8:string(8)|f9:wstring(2)|f10:string(8)|f11:wstring(2)|f12:date|f13:time|f14:datetime+1|256|32768|4294967296|1.10000|1.1000|1.1000|plátano|香蕉|plátano|香蕉|2013-12-31|23:34:56|2013-12-31 23:34:56
+ test-data/samples_of_various_field_types.yxdb view
binary file changed (absent → 2691 bytes)
+ test-data/samples_without_header.csv view
@@ -0,0 +1,1 @@+1|256|32768|4294967296|1.10000|1.1000|1.1000|plátano|香蕉|plátano|香蕉|2013-12-31|23:34:56|2013-12-31 23:34:56
+ test-data/signed.csv view
@@ -0,0 +1,2 @@+f1:int(8)|f2:int(16)|f3:int(32)|f4:int(64)|f5:decimal(7,5)|f6:float|f7:double+-1|-256|-32768|-4294967296|1.10000|-1.1000|-1.1000
yxdb-utils.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.0+version: 0.1.0.1 -- A short (one-line) description of the package. synopsis: Utilities for reading and writing Alteryx .yxdb files@@ -41,6 +41,10 @@ -- Constraint on the version of Cabal needed to build this package. cabal-version: >=1.8 +extra-source-files:+ test-data/*.csv+ test-data/*.yxdb+ executable csv2yxdb hs-source-dirs: bin-src main-is: Csv2Yxdb.hs@@ -108,6 +112,13 @@ test-suite yxdb-tests ghc-options: -O2 -fprof-auto hs-source-dirs: src, .+ other-modules:+ Tests.Codec.Compression.LZF.ByteString+ Tests.Data.Binary.C+ Tests.Database.Alteryx+ Tests.Database.Alteryx.Arbitrary+ Tests.Database.Utils+ Tests.Main type: exitcode-stdio-1.0 build-depends: Codec-Compression-LZF,@@ -152,7 +163,6 @@ buildable: True hs-source-dirs: src ghc-options: -rtsopts -with-rtsopts=-M512m- source-repository head type: git location: https://github.com/MichaelBurge/yxdb-utils