{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE OverloadedStrings #-}
module Test.Hspec.BenchGolden.Lenses
(
_statsMean
, _statsStddev
, _statsMedian
, _statsMin
, _statsMax
, _statsTrimmedMean
, _statsMAD
, _statsIQR
, metricFor
, varianceFor
, Expectation(..)
, Tolerance(..)
, expect
, expectStat
, checkExpectation
, withinPercent
, withinAbsolute
, withinHybrid
, mustImprove
, mustRegress
, (@~)
, (@<)
, (@<<)
, (@>>)
, (&&~)
, (||~)
, percentDiff
, absDiff
, toleranceFromExpectation
, toleranceValues
) where
import Lens.Micro
import Test.Hspec.BenchGolden.Types
_statsMean :: Lens' GoldenStats Double
_statsMean :: Lens' GoldenStats Double
_statsMean Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsMean = x }) (Double -> f Double
f (GoldenStats -> Double
statsMean GoldenStats
s))
_statsStddev :: Lens' GoldenStats Double
_statsStddev :: Lens' GoldenStats Double
_statsStddev Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsStddev = x }) (Double -> f Double
f (GoldenStats -> Double
statsStddev GoldenStats
s))
_statsMedian :: Lens' GoldenStats Double
_statsMedian :: Lens' GoldenStats Double
_statsMedian Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsMedian = x }) (Double -> f Double
f (GoldenStats -> Double
statsMedian GoldenStats
s))
_statsMin :: Lens' GoldenStats Double
_statsMin :: Lens' GoldenStats Double
_statsMin Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsMin = x }) (Double -> f Double
f (GoldenStats -> Double
statsMin GoldenStats
s))
_statsMax :: Lens' GoldenStats Double
_statsMax :: Lens' GoldenStats Double
_statsMax Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsMax = x }) (Double -> f Double
f (GoldenStats -> Double
statsMax GoldenStats
s))
_statsTrimmedMean :: Lens' GoldenStats Double
_statsTrimmedMean :: Lens' GoldenStats Double
_statsTrimmedMean Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsTrimmedMean = x }) (Double -> f Double
f (GoldenStats -> Double
statsTrimmedMean GoldenStats
s))
_statsMAD :: Lens' GoldenStats Double
_statsMAD :: Lens' GoldenStats Double
_statsMAD Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsMAD = x }) (Double -> f Double
f (GoldenStats -> Double
statsMAD GoldenStats
s))
_statsIQR :: Lens' GoldenStats Double
_statsIQR :: Lens' GoldenStats Double
_statsIQR Double -> f Double
f GoldenStats
s = (Double -> GoldenStats) -> f Double -> f GoldenStats
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Double
x -> GoldenStats
s { statsIQR = x }) (Double -> f Double
f (GoldenStats -> Double
statsIQR GoldenStats
s))
metricFor :: BenchConfig -> Lens' GoldenStats Double
metricFor :: BenchConfig -> Lens' GoldenStats Double
metricFor BenchConfig
cfg = if BenchConfig -> Bool
useRobustStatistics BenchConfig
cfg
then (Double -> f Double) -> GoldenStats -> f GoldenStats
Lens' GoldenStats Double
_statsTrimmedMean
else (Double -> f Double) -> GoldenStats -> f GoldenStats
Lens' GoldenStats Double
_statsMean
varianceFor :: BenchConfig -> Lens' GoldenStats Double
varianceFor :: BenchConfig -> Lens' GoldenStats Double
varianceFor BenchConfig
cfg = if BenchConfig -> Bool
useRobustStatistics BenchConfig
cfg
then (Double -> f Double) -> GoldenStats -> f GoldenStats
Lens' GoldenStats Double
_statsMAD
else (Double -> f Double) -> GoldenStats -> f GoldenStats
Lens' GoldenStats Double
_statsStddev
data Tolerance
= Percent !Double
| Absolute !Double
| Hybrid !Double !Double
| MustImprove !Double
| MustRegress !Double
deriving (Int -> Tolerance -> ShowS
[Tolerance] -> ShowS
Tolerance -> String
(Int -> Tolerance -> ShowS)
-> (Tolerance -> String)
-> ([Tolerance] -> ShowS)
-> Show Tolerance
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tolerance -> ShowS
showsPrec :: Int -> Tolerance -> ShowS
$cshow :: Tolerance -> String
show :: Tolerance -> String
$cshowList :: [Tolerance] -> ShowS
showList :: [Tolerance] -> ShowS
Show, Tolerance -> Tolerance -> Bool
(Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Bool) -> Eq Tolerance
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tolerance -> Tolerance -> Bool
== :: Tolerance -> Tolerance -> Bool
$c/= :: Tolerance -> Tolerance -> Bool
/= :: Tolerance -> Tolerance -> Bool
Eq)
data Expectation
= ExpectStat !(Lens' GoldenStats Double) !Tolerance
| And !Expectation !Expectation
| Or !Expectation !Expectation
instance Eq Expectation where
ExpectStat Lens' GoldenStats Double
_ Tolerance
tol1 == :: Expectation -> Expectation -> Bool
== ExpectStat Lens' GoldenStats Double
_ Tolerance
tol2 = Tolerance
tol1 Tolerance -> Tolerance -> Bool
forall a. Eq a => a -> a -> Bool
== Tolerance
tol2
And Expectation
e1 Expectation
e2 == And Expectation
e3 Expectation
e4 = Expectation
e1 Expectation -> Expectation -> Bool
forall a. Eq a => a -> a -> Bool
== Expectation
e3 Bool -> Bool -> Bool
&& Expectation
e2 Expectation -> Expectation -> Bool
forall a. Eq a => a -> a -> Bool
== Expectation
e4
Or Expectation
e1 Expectation
e2 == Or Expectation
e3 Expectation
e4 = Expectation
e1 Expectation -> Expectation -> Bool
forall a. Eq a => a -> a -> Bool
== Expectation
e3 Bool -> Bool -> Bool
&& Expectation
e2 Expectation -> Expectation -> Bool
forall a. Eq a => a -> a -> Bool
== Expectation
e4
Expectation
_ == Expectation
_ = Bool
False
instance Show Expectation where
show :: Expectation -> String
show (ExpectStat Lens' GoldenStats Double
_ Tolerance
tol) = String
"expect <field> " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Tolerance -> String
forall a. Show a => a -> String
show Tolerance
tol
show (And Expectation
e1 Expectation
e2) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expectation -> String
forall a. Show a => a -> String
show Expectation
e1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" &&~ " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expectation -> String
forall a. Show a => a -> String
show Expectation
e2 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
show (Or Expectation
e1 Expectation
e2) = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expectation -> String
forall a. Show a => a -> String
show Expectation
e1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" ||~ " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Expectation -> String
forall a. Show a => a -> String
show Expectation
e2 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
expect :: Lens' GoldenStats Double -> Tolerance -> Expectation
expect :: Lens' GoldenStats Double -> Tolerance -> Expectation
expect = Lens' GoldenStats Double -> Tolerance -> Expectation
ExpectStat
expectStat :: Lens' GoldenStats Double -> Tolerance -> Expectation
expectStat :: Lens' GoldenStats Double -> Tolerance -> Expectation
expectStat = Lens' GoldenStats Double -> Tolerance -> Expectation
expect
checkExpectation :: Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation :: Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation (ExpectStat Lens' GoldenStats Double
lns Tolerance
tol) GoldenStats
golden GoldenStats
actual =
let baseline :: Double
baseline = GoldenStats
golden GoldenStats -> Getting Double GoldenStats Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double GoldenStats Double
Lens' GoldenStats Double
lns
current :: Double
current = GoldenStats
actual GoldenStats -> Getting Double GoldenStats Double -> Double
forall s a. s -> Getting a s a -> a
^. Getting Double GoldenStats Double
Lens' GoldenStats Double
lns
in Tolerance -> Double -> Double -> Bool
checkTolerance Tolerance
tol Double
baseline Double
current
checkExpectation (And Expectation
e1 Expectation
e2) GoldenStats
golden GoldenStats
actual =
Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation Expectation
e1 GoldenStats
golden GoldenStats
actual Bool -> Bool -> Bool
&& Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation Expectation
e2 GoldenStats
golden GoldenStats
actual
checkExpectation (Or Expectation
e1 Expectation
e2) GoldenStats
golden GoldenStats
actual =
Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation Expectation
e1 GoldenStats
golden GoldenStats
actual Bool -> Bool -> Bool
|| Expectation -> GoldenStats -> GoldenStats -> Bool
checkExpectation Expectation
e2 GoldenStats
golden GoldenStats
actual
checkTolerance :: Tolerance -> Double -> Double -> Bool
checkTolerance :: Tolerance -> Double -> Double -> Bool
checkTolerance (Percent Double
pct) Double
baseline Double
current =
Double -> Double -> Double -> Bool
withinPercent Double
pct Double
baseline Double
current
checkTolerance (Absolute Double
absThreshold) Double
baseline Double
current =
Double -> Double -> Double -> Bool
withinAbsolute Double
absThreshold Double
baseline Double
current
checkTolerance (Hybrid Double
pct Double
absThreshold) Double
baseline Double
current =
Double -> Double -> Double -> Double -> Bool
withinHybrid Double
pct Double
absThreshold Double
baseline Double
current
checkTolerance (MustImprove Double
minPct) Double
baseline Double
current =
Double -> Double -> Double -> Bool
mustImprove Double
minPct Double
baseline Double
current
checkTolerance (MustRegress Double
minPct) Double
baseline Double
current =
Double -> Double -> Double -> Bool
mustRegress Double
minPct Double
baseline Double
current
withinPercent :: Double -> Double -> Double -> Bool
withinPercent :: Double -> Double -> Double -> Bool
withinPercent Double
tolerance Double
baseline Double
actual =
let pct :: Double
pct = Double -> Double -> Double
percentDiff Double
baseline Double
actual
in Double -> Double
forall a. Num a => a -> a
abs Double
pct Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
tolerance
withinAbsolute :: Double -> Double -> Double -> Bool
withinAbsolute :: Double -> Double -> Double -> Bool
withinAbsolute Double
threshold Double
baseline Double
actual =
Double -> Double -> Double
absDiff Double
baseline Double
actual Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
threshold
withinHybrid :: Double -> Double -> Double -> Double -> Bool
withinHybrid :: Double -> Double -> Double -> Double -> Bool
withinHybrid Double
pctTolerance Double
absThreshold Double
baseline Double
actual =
Double -> Double -> Double -> Bool
withinPercent Double
pctTolerance Double
baseline Double
actual Bool -> Bool -> Bool
||
Double -> Double -> Double -> Bool
withinAbsolute Double
absThreshold Double
baseline Double
actual
mustImprove :: Double -> Double -> Double -> Bool
mustImprove :: Double -> Double -> Double -> Bool
mustImprove Double
minPercent Double
baseline Double
actual =
let pct :: Double
pct = Double -> Double -> Double
percentDiff Double
baseline Double
actual
in Double
pct Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double -> Double
forall a. Num a => a -> a
negate Double
minPercent
mustRegress :: Double -> Double -> Double -> Bool
mustRegress :: Double -> Double -> Double -> Bool
mustRegress Double
minPercent Double
baseline Double
actual =
let pct :: Double
pct = Double -> Double -> Double
percentDiff Double
baseline Double
actual
in Double
pct Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
minPercent
(@~) :: Double -> Double -> Double -> Bool
@~ :: Double -> Double -> Double -> Bool
(@~) Double
baseline Double
tolerance Double
actual = Double -> Double -> Double -> Bool
withinPercent Double
tolerance Double
baseline Double
actual
infixl 4 @~
(@<) :: Double -> Double -> Double -> Bool
@< :: Double -> Double -> Double -> Bool
(@<) Double
baseline Double
threshold Double
actual = Double -> Double -> Double -> Bool
withinAbsolute Double
threshold Double
baseline Double
actual
infixl 4 @<
(@<<) :: Double -> Double -> Double -> Bool
@<< :: Double -> Double -> Double -> Bool
(@<<) Double
baseline Double
minPercent Double
actual = Double -> Double -> Double -> Bool
mustImprove Double
minPercent Double
baseline Double
actual
infixl 4 @<<
(@>>) :: Double -> Double -> Double -> Bool
@>> :: Double -> Double -> Double -> Bool
(@>>) Double
baseline Double
minPercent Double
actual = Double -> Double -> Double -> Bool
mustRegress Double
minPercent Double
baseline Double
actual
infixl 4 @>>
(&&~) :: Expectation -> Expectation -> Expectation
&&~ :: Expectation -> Expectation -> Expectation
(&&~) = Expectation -> Expectation -> Expectation
And
infixr 3 &&~
(||~) :: Expectation -> Expectation -> Expectation
||~ :: Expectation -> Expectation -> Expectation
(||~) = Expectation -> Expectation -> Expectation
Or
infixr 2 ||~
percentDiff :: Double -> Double -> Double
percentDiff :: Double -> Double -> Double
percentDiff Double
baseline Double
actual
| Double
baseline Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 = if Double
actual Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 then Double
0 else Double
100
| Bool
otherwise = ((Double
actual Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
baseline) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
baseline) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
100
absDiff :: Double -> Double -> Double
absDiff :: Double -> Double -> Double
absDiff Double
baseline Double
actual = Double -> Double
forall a. Num a => a -> a
abs (Double
actual Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
baseline)
toleranceFromExpectation :: Expectation -> (Double, Maybe Double)
toleranceFromExpectation :: Expectation -> (Double, Maybe Double)
toleranceFromExpectation (ExpectStat Lens' GoldenStats Double
_ Tolerance
tol) = Tolerance -> (Double, Maybe Double)
toleranceValues Tolerance
tol
toleranceFromExpectation (And Expectation
e1 Expectation
_) = Expectation -> (Double, Maybe Double)
toleranceFromExpectation Expectation
e1
toleranceFromExpectation (Or Expectation
e1 Expectation
_) = Expectation -> (Double, Maybe Double)
toleranceFromExpectation Expectation
e1
toleranceValues :: Tolerance -> (Double, Maybe Double)
toleranceValues :: Tolerance -> (Double, Maybe Double)
toleranceValues (Percent Double
pct) = (Double
pct, Maybe Double
forall a. Maybe a
Nothing)
toleranceValues (Absolute Double
abs_) = (Double
0, Double -> Maybe Double
forall a. a -> Maybe a
Just Double
abs_)
toleranceValues (Hybrid Double
pct Double
abs_) = (Double
pct, Double -> Maybe Double
forall a. a -> Maybe a
Just Double
abs_)
toleranceValues (MustImprove Double
pct) = (Double
pct, Maybe Double
forall a. Maybe a
Nothing)
toleranceValues (MustRegress Double
pct) = (Double
pct, Maybe Double
forall a. Maybe a
Nothing)