Fix formatting and errors
This commit is contained in:
parent
35025d9359
commit
37eabfbc60
25
app/Main.hs
25
app/Main.hs
@ -1,27 +1,22 @@
|
|||||||
module Main where
|
module Main
|
||||||
|
( main
|
||||||
import System.Environment (getArgs)
|
) where
|
||||||
import System.Exit
|
|
||||||
import Text.Parsec.Error (ParseError)
|
|
||||||
|
|
||||||
import Data.Dates
|
import Data.Dates
|
||||||
import Pattern
|
import Pattern (match)
|
||||||
|
import System.Environment (getArgs)
|
||||||
|
import System.Exit
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
args <- getArgs
|
args <- getArgs
|
||||||
dt <- getCurrentDateTime
|
currentDateTime <- getCurrentDateTime
|
||||||
exitWith $
|
exitWith $
|
||||||
case processArgs args dt of
|
case processArgs args currentDateTime of
|
||||||
Just True -> ExitSuccess
|
Just True -> ExitSuccess
|
||||||
Just False -> ExitFailure 1
|
Just False -> ExitFailure 1
|
||||||
Nothing -> ExitFailure 2
|
Nothing -> ExitFailure 2
|
||||||
|
|
||||||
processArgs :: [String] -> DateTime -> Maybe Bool
|
processArgs :: [String] -> DateTime -> Maybe Bool
|
||||||
processArgs [ptn] dt = safeMatch ptn dt
|
processArgs [ptn] dt = match ptn dt
|
||||||
processArgs [ptn, time] dt = matchGivenTime ptn (parseDate dt time)
|
processArgs _ _ = Nothing
|
||||||
processArgs _ _ = Nothing
|
|
||||||
|
|
||||||
matchGivenTime :: String -> Either ParseError DateTime -> Maybe Bool
|
|
||||||
matchGivenTime _ (Left _) = Nothing
|
|
||||||
matchGivenTime ptn (Right dt) = safeMatch ptn dt
|
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
module Constraint where
|
module Constraint
|
||||||
|
( Constraint(..)
|
||||||
|
, inRange
|
||||||
|
, inside
|
||||||
|
) where
|
||||||
|
|
||||||
data Constraint = Constraint
|
data Constraint = Constraint
|
||||||
{ lower :: Int
|
{ lower :: Int
|
||||||
, upper :: Int
|
, upper :: Int
|
||||||
} deriving (Show, Eq)
|
} deriving (Show, Eq)
|
||||||
|
|
||||||
makeRangeFromNumber :: Int -> Constraint
|
|
||||||
makeRangeFromNumber x = Constraint x x
|
|
||||||
|
|
||||||
inside :: (Int, Int) -> Constraint -> Bool
|
inside :: (Int, Int) -> Constraint -> Bool
|
||||||
inside (x, y) (Constraint lower upper) = x >= lower && y <= upper
|
inside (x, y) (Constraint lw up) = x >= lw && y <= up
|
||||||
|
|
||||||
inRange :: Int -> Constraint -> Bool
|
inRange :: Int -> Constraint -> Bool
|
||||||
inRange x = inside (x, x)
|
inRange x = inside (x, x)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
module Field where
|
module Field
|
||||||
|
( module Field
|
||||||
|
) where
|
||||||
|
|
||||||
import Constraint
|
import Constraint
|
||||||
import Data.Char (isDigit)
|
import Data.Char (isDigit)
|
||||||
@ -44,11 +46,12 @@ parseFieldRange text constraint
|
|||||||
| text == "*" = Just All
|
| text == "*" = Just All
|
||||||
| isJust number = Just (Range (fromJust number) (fromJust number))
|
| isJust number = Just (Range (fromJust number) (fromJust number))
|
||||||
| isJust range = Just (uncurry Range (fromJust range))
|
| isJust range = Just (uncurry Range (fromJust range))
|
||||||
| isJust sequence = fmap Sequence sequence
|
| isJust valueSequence = fmap Sequence valueSequence
|
||||||
|
| otherwise = Nothing
|
||||||
where
|
where
|
||||||
number = parseNumber text constraint
|
number = parseNumber text constraint
|
||||||
range = parseRange text constraint
|
range = parseRange text constraint
|
||||||
sequence = parseSequence text constraint
|
valueSequence = parseSequence text constraint
|
||||||
|
|
||||||
isNumber :: String -> Bool
|
isNumber :: String -> Bool
|
||||||
isNumber = all isDigit
|
isNumber = all isDigit
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
module Helper where
|
module Helper
|
||||||
|
( wordsWhen
|
||||||
|
) where
|
||||||
|
|
||||||
wordsWhen :: (Char -> Bool) -> String -> [String]
|
wordsWhen :: (Char -> Bool) -> String -> [String]
|
||||||
wordsWhen p s =
|
wordsWhen p s =
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
module Pattern
|
module Pattern
|
||||||
( Pattern(..)
|
( Pattern(..)
|
||||||
, match
|
, match
|
||||||
, safeMatch
|
|
||||||
, parse
|
, parse
|
||||||
, check
|
, check
|
||||||
, createParts
|
, createFields
|
||||||
, parseField
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Constraint
|
import Constraint
|
||||||
@ -20,16 +18,10 @@ data Pattern = Pattern
|
|||||||
, cmonth :: Field
|
, cmonth :: Field
|
||||||
, cweek :: Field
|
, cweek :: Field
|
||||||
, cyear :: Field
|
, cyear :: Field
|
||||||
}
|
} deriving (Show)
|
||||||
|
|
||||||
match :: String -> DateTime -> Bool
|
match :: String -> DateTime -> Maybe Bool
|
||||||
match s d =
|
match s d =
|
||||||
case parse s of
|
|
||||||
Just p -> check p d
|
|
||||||
Nothing -> error "Parse error"
|
|
||||||
|
|
||||||
safeMatch :: String -> DateTime -> Maybe Bool
|
|
||||||
safeMatch s d =
|
|
||||||
case parse s of
|
case parse s of
|
||||||
Just p -> Just (check p d)
|
Just p -> Just (check p d)
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
@ -39,7 +31,7 @@ parse s
|
|||||||
| isInvalid = Nothing
|
| isInvalid = Nothing
|
||||||
| otherwise = Just (createPattern $ catMaybes parts)
|
| otherwise = Just (createPattern $ catMaybes parts)
|
||||||
where
|
where
|
||||||
parts = createParts s
|
parts = createFields s
|
||||||
isInvalid = not (checkParts parts)
|
isInvalid = not (checkParts parts)
|
||||||
createPattern xs =
|
createPattern xs =
|
||||||
Pattern
|
Pattern
|
||||||
@ -51,9 +43,10 @@ parse s
|
|||||||
, cyear = xs !! 5
|
, cyear = xs !! 5
|
||||||
}
|
}
|
||||||
|
|
||||||
createParts s = zipWith (curry f) parsers (words s)
|
createFields :: String -> [Maybe Field]
|
||||||
|
createFields text = zipWith (curry f) parsers (words text)
|
||||||
where
|
where
|
||||||
f (g, s) = g s
|
f (parser, s) = parser s
|
||||||
|
|
||||||
checkParts :: [Maybe Field] -> Bool
|
checkParts :: [Maybe Field] -> Bool
|
||||||
checkParts xs
|
checkParts xs
|
||||||
@ -64,18 +57,25 @@ checkParts xs
|
|||||||
parseFieldAdapter :: Constraint -> String -> Maybe Field
|
parseFieldAdapter :: Constraint -> String -> Maybe Field
|
||||||
parseFieldAdapter c t = parseField t c
|
parseFieldAdapter c t = parseField t c
|
||||||
|
|
||||||
|
parseMinute :: String -> Maybe Field
|
||||||
parseMinute = parseFieldAdapter (Constraint 0 59)
|
parseMinute = parseFieldAdapter (Constraint 0 59)
|
||||||
|
|
||||||
parseHour = parseFieldAdapter (Constraint 0 59)
|
parseHour :: String -> Maybe Field
|
||||||
|
parseHour = parseFieldAdapter (Constraint 0 23)
|
||||||
|
|
||||||
|
parseDay :: String -> Maybe Field
|
||||||
parseDay = parseFieldAdapter (Constraint 1 31)
|
parseDay = parseFieldAdapter (Constraint 1 31)
|
||||||
|
|
||||||
|
parseMonth :: String -> Maybe Field
|
||||||
parseMonth = parseFieldAdapter (Constraint 1 12)
|
parseMonth = parseFieldAdapter (Constraint 1 12)
|
||||||
|
|
||||||
|
parseWeek :: String -> Maybe Field
|
||||||
parseWeek = parseFieldAdapter (Constraint 1 7)
|
parseWeek = parseFieldAdapter (Constraint 1 7)
|
||||||
|
|
||||||
|
parseYear :: String -> Maybe Field
|
||||||
parseYear = parseFieldAdapter (Constraint 0 9999)
|
parseYear = parseFieldAdapter (Constraint 0 9999)
|
||||||
|
|
||||||
|
parsers :: [String -> Maybe Field]
|
||||||
parsers = [parseMinute, parseHour, parseDay, parseMonth, parseWeek, parseYear]
|
parsers = [parseMinute, parseHour, parseDay, parseMonth, parseWeek, parseYear]
|
||||||
|
|
||||||
check :: Pattern -> DateTime -> Bool
|
check :: Pattern -> DateTime -> Bool
|
||||||
|
@ -12,7 +12,5 @@ main = hspec spec
|
|||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec =
|
spec =
|
||||||
describe "Constraint" $ do
|
describe "Constraint" $ do
|
||||||
it "can be created from number" $
|
|
||||||
makeRangeFromNumber 10 `shouldBe` Constraint 10 10
|
|
||||||
it "validate number" $ 10 `inRange` Constraint 0 10 `shouldBe` True
|
it "validate number" $ 10 `inRange` Constraint 0 10 `shouldBe` True
|
||||||
it "validate number" $ 10 `inRange` Constraint 15 20 `shouldBe` False
|
it "validate number" $ 10 `inRange` Constraint 15 20 `shouldBe` False
|
||||||
|
@ -34,23 +34,23 @@ spec = do
|
|||||||
describe "Step can be created from" $ do
|
describe "Step can be created from" $ do
|
||||||
it "empty string" $ parseFieldStep "" `shouldBe` Just Every
|
it "empty string" $ parseFieldStep "" `shouldBe` Just Every
|
||||||
it "number" $ parseFieldStep "5" `shouldBe` Just (Step 5)
|
it "number" $ parseFieldStep "5" `shouldBe` Just (Step 5)
|
||||||
describe "Step cant'b created from" $ do
|
describe "Step cant'b created from" $
|
||||||
it "word" $ parseFieldStep "hello" `shouldBe` Nothing
|
it "word" $ parseFieldStep "hello" `shouldBe` Nothing
|
||||||
-- Field validation
|
-- Field validation
|
||||||
describe "Field can be created from" $ do
|
describe "Field can be created from" $ do
|
||||||
it "asterisk" $
|
it "asterisk" $
|
||||||
parseField "*" (Constraint 0 59) `shouldBe` Just (Field All Every)
|
parseField "*" (Constraint 0 59) `shouldBe` Just (Field All Every)
|
||||||
it "asterisk with step" $ do
|
it "asterisk with step" $
|
||||||
parseField "*/5" (Constraint 0 59) `shouldBe` Just (Field All (Step 5))
|
parseField "*/5" (Constraint 0 59) `shouldBe` Just (Field All (Step 5))
|
||||||
it "number with step" $ do
|
it "number with step" $
|
||||||
parseField "10/5" (Constraint 0 59) `shouldBe`
|
parseField "10/5" (Constraint 0 59) `shouldBe`
|
||||||
Just (Field (Range 10 10) (Step 5))
|
Just (Field (Range 10 10) (Step 5))
|
||||||
it "range with step" $ do
|
it "range with step" $
|
||||||
parseField "0-59/5" (Constraint 0 59) `shouldBe`
|
parseField "0-59/5" (Constraint 0 59) `shouldBe`
|
||||||
Just (Field (Range 0 59) (Step 5))
|
Just (Field (Range 0 59) (Step 5))
|
||||||
it "sequence with step" $ do
|
it "sequence with step" $
|
||||||
parseField "1,3,4/5" (Constraint 0 59) `shouldBe`
|
parseField "1,3,4/5" (Constraint 0 59) `shouldBe`
|
||||||
Just (Field (Sequence [1, 3, 4]) (Step 5))
|
Just (Field (Sequence [1, 3, 4]) (Step 5))
|
||||||
-- Field match
|
-- Field match
|
||||||
describe "Field can match" $ do
|
describe "Field can match" $ do
|
||||||
it "number" $ count (Field All Every) [0 .. 59] `shouldBe` 60
|
it "number" $ count (Field All Every) [0 .. 59] `shouldBe` 60
|
||||||
|
@ -4,6 +4,7 @@ module PatternSpec
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Dates
|
import Data.Dates
|
||||||
|
import Data.Maybe
|
||||||
import Pattern
|
import Pattern
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
@ -11,13 +12,13 @@ main :: IO ()
|
|||||||
main = hspec spec
|
main = hspec spec
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec =
|
||||||
describe "Cron pattern" $ do
|
describe "Cron pattern" $ do
|
||||||
it "createParts" $ length (createParts "* * * * * *") `shouldBe` 6
|
it "createFields" $ length (createFields "* * * * * *") `shouldBe` 6
|
||||||
it "matches fixed time" $
|
it "matches fixed time" $
|
||||||
let ptn = "* * * * * *"
|
let ptn = "* * * * * *"
|
||||||
date = DateTime 2017 10 11 0 0 0
|
date = DateTime 2017 10 11 0 0 0
|
||||||
in match ptn date `shouldBe` True
|
in match ptn date `shouldBe` Just True
|
||||||
it "matches all minutes" $
|
it "matches all minutes" $
|
||||||
let ptn = "* * * * * *"
|
let ptn = "* * * * * *"
|
||||||
dates = [DateTime 2017 10 11 0 i 0 | i <- [0 .. 59]]
|
dates = [DateTime 2017 10 11 0 i 0 | i <- [0 .. 59]]
|
||||||
@ -25,12 +26,16 @@ spec = do
|
|||||||
it "matches exactly moment" $
|
it "matches exactly moment" $
|
||||||
let date = DateTime 2017 10 11 0 0 0
|
let date = DateTime 2017 10 11 0 0 0
|
||||||
ptn = "0 0 11 10 * 2017"
|
ptn = "0 0 11 10 * 2017"
|
||||||
in match ptn date `shouldBe` True
|
in match ptn date `shouldBe` Just True
|
||||||
|
it "matches moment" $
|
||||||
|
let date = DateTime 2017 10 10 12 10 0
|
||||||
|
ptn = "* 12 * * * *"
|
||||||
|
in match ptn date `shouldBe` Just True
|
||||||
|
|
||||||
countMatches :: String -> [DateTime] -> Int
|
countMatches :: String -> [DateTime] -> Int
|
||||||
countMatches p xs = sum $ map (f p) xs
|
countMatches p xs = sum $ map (f p) xs
|
||||||
where
|
where
|
||||||
f x d =
|
f x d =
|
||||||
if match x d
|
if isJust $ match x d
|
||||||
then 1
|
then 1
|
||||||
else 0
|
else 0
|
||||||
|
Loading…
Reference in New Issue
Block a user