Improving TimeLog specs

[?]
Apr 22, 2015, 5:46 PM
5DRIWGLUKMQZU2ZPBXSTLAWJKAMOD5YXAHM5LEDQHDFGYYLHWCDQC

Dependencies

  • [2] WJO37T74 Restored the single test to functionality.
  • [3] 7KZP4RHZ Switch from Data.Time to Data.Thyme
  • [4] EMVTF2IW WIP moving back to snap.
  • [5] 2KZPOGRB Once you get Haskell to compile, the tests pass!
  • [6] PBD7LZYQ Postgres & auth are beginning to function.
  • [7] IZEVQF62 Work in progress replacing sqlite with postgres.
  • [8] 64C6AWH6 Rename Ananke -> Quixotic, project reboot.
  • [9] FD7SV5I6 Fix handling of event_t columns.
  • [10] WO2MINIF Auctions now compile!
  • [11] HE3JTXO3 Added client call to payouts.
  • [12] GKGVYBZG Added JSON serialization to TimeLog
  • [13] EQXRXRZD Changed to use tasty instead of test-framework
  • [14] 7DBNV3GV Initial, stack-based impl of time log event reduction.
  • [15] NMWWP4ZN Trying out Hspec
  • [16] A6HKMINB Attempting to improve JSON handling.
  • [17] EZQG2APB Update task list.
  • [18] NVOCQVAS Initial failing tests.
  • [19] TLQ72DSJ Lenses, sqlite-simple
  • [20] 4IQVQL4T Added client for payouts endpoint.
  • [21] RSEB2NFG Replacing Snap with Scotty.
  • [22] BROSTG5K Beginning of modularization of server.
  • [23] N4NDAZYT Initial implementation of payouts.
  • [24] JV3UEPNC Fix Aeson constructors.
  • [25] TJEUE7TY Added OverloadedStrings to eliminate Text fiddling.
  • [26] Y35QCWYW Minor improvement in WorkIndex type to eliminate duplicated information.
  • [27] SLL7262C Make depreciation functions more flexible.
  • [28] 4QX5E5AC Initial compilation of payouts function succeeds.
  • [29] P6NR2CGX Beginning of implementation of depreciation.
  • [30] OBFPJS2G Project successfully builds and tests under nix.
  • [31] 7XN3I3QJ Add 'loggedIntervals' endpoint.

Change contents

  • replacement in lib/Quixotic/TimeLog.hs at line 12
    [4.3620][4.93:107](),[4.3854][4.93:107](),[4.93][4.93:107]()
    , WorkIndex
    [4.3854]
    [4.5479]
    , WorkIndex(WorkIndex), _WorkIndex
  • edit in lib/Quixotic/TimeLog.hs at line 31
    [3.808]
    [4.65]
    import Data.Heap as H
    import Data.List.NonEmpty as L
  • edit in lib/Quixotic/TimeLog.hs at line 45
    [4.5415]
    [4.3716]
    instance Ord EventType where
    compare StartWork StopWork = LT
    compare StopWork StartWork = GT
    compare _ _ = EQ
  • edit in lib/Quixotic/TimeLog.hs at line 73
    [4.4261]
    [4.1724]
    instance Ord LogEntry where
    compare a b =
    let ordElems e = (e ^. (event.eventTime), e ^. (event.eventType), e ^. btcAddr)
    in ordElems a `compare` ordElems b
  • replacement in lib/Quixotic/TimeLog.hs at line 112
    [4.49][4.337:377](),[4.6562][4.337:377](),[4.2287][4.337:377]()
    type WorkIndex = Map BtcAddr [Interval]
    [4.6562]
    [4.378]
    newtype WorkIndex = WorkIndex (Map BtcAddr (NonEmpty Interval)) deriving (Show, Eq)
    makePrisms ''WorkIndex
  • replacement in lib/Quixotic/TimeLog.hs at line 119
    [4.6599][4.6599:6693]()
    workIndexJSON widx = toJSON $ (fmap intervalJSON) <$> (MS.mapKeysWith (++) (^._BtcAddr) widx)
    [4.6599]
    [4.6693]
    workIndexJSON (WorkIndex widx) =
    toJSON $ (L.toList . fmap intervalJSON) <$> (MS.mapKeysMonotonic (^._BtcAddr) widx)
  • replacement in lib/Quixotic/TimeLog.hs at line 145
    [4.170][4.850:876](),[3.1819][4.850:876](),[4.588][4.850:876]()
    payouts dep ptime widx =
    [3.1819]
    [4.876]
    payouts dep ptime (WorkIndex widx) =
  • replacement in lib/Quixotic/TimeLog.hs at line 155
    [4.4420][4.4420:4504](),[4.4504][4.574:620]()
    let logSum :: RawIndex
    logSum = F.foldl' appendLogEntry MS.empty logEntries
    in fmap (fmap workInterval . snd) $ logSum
    [4.4420]
    [4.448]
    let sortedEntries :: Heap LogEntry
    sortedEntries = F.foldr H.insert H.empty $ logEntries
    rawIndex :: RawIndex
    rawIndex = F.foldl' appendLogEntry MS.empty $ sortedEntries
    accum k (_, l) m = case nonEmpty l of
    Just l' -> MS.insert k (workInterval <$> l') m
    Nothing -> m
    in WorkIndex $ MS.foldrWithKey accum MS.empty rawIndex
  • replacement in lib/Quixotic/TimeLog.hs at line 170
    [4.4654][4.4654:4694]()
    in insert (entry ^. btcAddr) acc idx
    [4.4654]
    [4.2252]
    in MS.insert (entry ^. btcAddr) acc idx
  • edit in lib/Quixotic/TimeLog.hs at line 172
    [4.2253]
    [4.2253]
    {-|
    - Find the set of accumulated log intervals and log entries
    - for a given BTC address, and concatenate the entry to the entry list.
    -}
  • replacement in quixotic.cabal at line 36
    [4.1143][4.6965:6988]()
    , template-haskell
    [4.1143]
    [4.3072]
    , base64-bytestring >= 1.0.0.1
  • edit in quixotic.cabal at line 38
    [4.3089]
    [4.1144]
    , blaze-builder
  • edit in quixotic.cabal at line 43
    [4.1854][4.1854:1892](),[4.1892][4.5048:5084]()
    , lens >= 4.4.0.2
    , safe >= 0.3.8
  • edit in quixotic.cabal at line 44
    [4.5120]
    [4.1892]
    , groups >= 0.4
    , heaps >= 0.3.1
    , hourglass >= 0.2.6 && < 0.3
    , lens >= 4.4.0.2
    , network-bitcoin >= 1.7.0
  • edit in quixotic.cabal at line 50
    [4.1909][4.5121:5169]()
    , sqlite-simple >= 0.4.8 && < 0.5
  • replacement in quixotic.cabal at line 51
    [4.7323][4.7323:7351]()
    , blaze-builder
    [4.7323]
    [4.1947]
    , safe >= 0.3.8
    , semigroups
    , sqlite-simple >= 0.4.8 && < 0.5
    , template-haskell
  • edit in quixotic.cabal at line 57
    [3.2886][4.2029:2111](),[4.2029][4.2029:2111](),[4.2111][4.1048:1084](),[4.1084][4.1162:1200]()
    , hourglass >= 0.2.6 && < 0.3
    , groups >= 0.4
    , network-bitcoin >= 1.7.0
    , base64-bytestring >= 1.0.0.1
  • edit in quixotic.cabal at line 73
    [4.2159][3.2907:2931]()
    , QuickCheck >= 2.7
  • edit in quixotic.cabal at line 78
    [4.2188]
    [4.2188]
    , hspec >= 1.8.1
    , iso8601-time
    , lens
    , QuickCheck >= 2.7
    , semigroups
  • edit in quixotic.cabal at line 85
    [3.2944][4.3130:3149](),[4.2210][4.3130:3149](),[4.3149][4.2210:2231](),[4.2210][4.2210:2231]()
    , iso8601-time
    , hspec >= 1.8.1
  • replacement in test/Quixotic/TimeLogSpec.hs at line 8
    [4.2657][4.182:200]()
    import Test.Hspec
    [4.2657]
    [4.5608]
    import Control.Lens ((^.))
    import Data.AffineSpace
    import Data.List.NonEmpty as L
    import Data.Map.Strict as M
    import Data.Time.ISO8601
    import Data.Thyme.Time as T
  • replacement in test/Quixotic/TimeLogSpec.hs at line 17
    [4.5654][4.5654:5683]()
    import Quixotic.TimeLog as L
    [4.5654]
    [4.269]
    import Quixotic.TimeLog
  • edit in test/Quixotic/TimeLogSpec.hs at line 19
    [4.270][3.3152:3176](),[4.3085][4.201:229](),[3.3176][4.201:229](),[4.3781][4.201:229](),[4.3895][4.332:357](),[4.357][3.3177:3256]()
    import Data.AffineSpace
    import Data.Map.Strict as M
    import Data.Time.ISO8601
    import Data.Thyme.Clock
    import Data.Thyme.Time
    import qualified Data.Text as T
  • edit in test/Quixotic/TimeLogSpec.hs at line 20
    [3.3279]
    [3.3279]
    import Test.Hspec
  • replacement in test/Quixotic/TimeLogSpec.hs at line 28
    [3.3434][3.3434:3491]()
    arbitrary = BtcAddr . T.pack <$> vectorOf 34 arbitrary
    [3.3434]
    [4.2088]
    arbitrary = BtcAddr . pack <$> vectorOf 34 arbitrary
  • replacement in test/Quixotic/TimeLogSpec.hs at line 32
    [3.3543][3.3543:3566]()
    start <- arbitrary
    [3.3543]
    [3.3566]
    startTime <- arbitrary
  • replacement in test/Quixotic/TimeLogSpec.hs at line 34
    [3.3589][3.3589:3640]()
    pure $ I.interval start (start .+^ delta)
    [3.3589]
    [4.358]
    pure $ I.interval startTime (startTime .+^ delta)
    instance Arbitrary WorkIndex where
    arbitrary =
    let record = (,) <$> arbitrary <*> (L.fromList <$> listOf1 arbitrary)
    in WorkIndex . M.fromList <$> listOf record
  • replacement in test/Quixotic/TimeLogSpec.hs at line 44
    [4.198][4.413:618](),[4.413][4.413:618]()
    it "reduces a log to a work index" $ do
    let testAddrs = catMaybes [ parseBtcAddr "123"
    , parseBtcAddr "456"
    , parseBtcAddr "789" ]
    [4.198]
    [4.4126]
    it "reduces a log to a work index" $
    let testAddrs = L.fromList $ catMaybes
    [ parseBtcAddr "123"
    , parseBtcAddr "456"
    , parseBtcAddr "789" ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 50
    [4.4127][3.3641:3807]()
    starts = toThyme <$> catMaybes [ parseISO8601 "2014-01-01T00:08:00Z"
    , parseISO8601 "2014-02-12T00:12:00Z" ]
    [4.4127]
    [4.4253]
    starts = L.fromList $ toThyme <$> catMaybes
    [ parseISO8601 "2014-01-01T00:08:00Z"
    , parseISO8601 "2014-02-12T00:12:00Z" ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 54
    [4.4254][3.3808:3974]()
    ends = toThyme <$> catMaybes [ parseISO8601 "2014-01-01T00:12:00Z"
    , parseISO8601 "2014-02-12T00:18:00Z" ]
    [4.4254]
    [4.2686]
    ends = L.fromList $ toThyme <$> catMaybes
    [ parseISO8601 "2014-01-01T00:12:00Z"
    , parseISO8601 "2014-02-12T00:18:00Z" ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 58
    [4.2687][4.905:944]()
    testLogEntries :: [LogEntry]
    [4.2687]
    [4.944]
    testLogEntries :: NonEmpty LogEntry
  • replacement in test/Quixotic/TimeLogSpec.hs at line 61
    [4.1004][4.3086:3132](),[4.3132][4.656:772]()
    (start', end') <- zip starts ends
    [ LogEntry addr (WorkEvent StartWork start' Nothing), LogEntry addr (WorkEvent StopWork end' Nothing) ]
    [4.1004]
    [4.417]
    (start', end') <- L.zip starts ends
    L.fromList [ LogEntry addr (WorkEvent StartWork start' Nothing)
    , LogEntry addr (WorkEvent StopWork end' Nothing) ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 65
    [4.418][4.1127:1197]()
    testIntervals :: [LogInterval]
    testIntervals = do
    [4.418]
    [4.1197]
    testIntervals :: NonEmpty LogInterval
    testIntervals = L.reverse $ do
  • replacement in test/Quixotic/TimeLogSpec.hs at line 68
    [4.1227][4.3213:3322]()
    (start', end') <- zip starts ends
    return $ LogInterval addr (I.interval start' end')
    [4.1227]
    [4.2824]
    (start', end') <- L.zip starts ends
    pure $ LogInterval addr (I.interval start' end')
    expected :: WorkIndex
    expected = WorkIndex . fromListWith (<>) . L.toList $ (intervalBtcAddr &&& pure . workInterval) <$> testIntervals
  • replacement in test/Quixotic/TimeLogSpec.hs at line 74
    [4.2825][4.1333:1396](),[4.1396][2.3:120]()
    expected0 :: Map BtcAddr ([LogEntry], [LogInterval])
    expected0 = fmap (const [] &&& id) . fromListWith (++) . fmap (intervalBtcAddr &&& return) $ testIntervals
    [4.2825]
    [4.493]
    in (workIndex testLogEntries) `shouldBe` expected
  • replacement in test/Quixotic/TimeLogSpec.hs at line 76
    [4.494][4.1515:1547](),[4.1547][2.121:183]()
    expected :: WorkIndex
    expected = fmap (fmap workInterval . snd) expected0
    [4.494]
    [4.4635]
    it "recovers a work index from events" $ property $
    \widx ->
    let ivalEntries addr ival = [ LogEntry addr (WorkEvent StartWork (ival ^. start) Nothing)
    , LogEntry addr (WorkEvent StopWork (ival ^. end) Nothing) ]
  • replacement in test/Quixotic/TimeLogSpec.hs at line 81
    [4.4636][4.4030:4083]()
    (workIndex testLogEntries) `shouldBe` expected
    [4.4636]
    [3.3975]
    acc k a b = b ++ (L.toList a >>= ivalEntries k)
    logEntries = foldrWithKey acc [] (widx ^. _WorkIndex)
    in workIndex logEntries `shouldBe` widx
  • edit in test/Quixotic/TimeLogSpec.hs at line 93
    [4.977]
    {--
    (fromList [
    (BtcAddr "S\187\156\a\SOx\229`[\133a%7o%'XBt\249\226\n\ENQ\SOH\GS<\241WU5{Si\251",
    [ Interval {_start = 1858-11-16 23:59:59.999997 UTC, _end = 1858-11-16 23:59:59.999997 UTC}
    , Interval {_start = 1858-11-16 23:59:59.999998 UTC, _end = 1858-11-17 00:00:00.000002 UTC}]),
    (BtcAddr "\138;\GS\132U0\SUB\ESCf[\NAKo`\ACKR[\EMq\b\v\159\184u\ACK&jS#n#?\SI&v",
    [Interval {_start = 1858-11-16 23:59:59.999999 UTC, _end = 1858-11-17 00:00:00 UTC}
    ,Interval {_start = 1858-11-17 00:00:00.000002 UTC, _end = 1858-11-17 00:00:00.000006 UTC}
    ,Interval {_start = 1858-11-16 23:59:59.999994 UTC, _end = 1858-11-16 23:59:59.999998 UTC}])
    ])
    -}