Fix formatting and errors

This commit is contained in:
Anton Vakhrushev 2017-11-12 12:53:43 +03:00
parent 35025d9359
commit 37eabfbc60
8 changed files with 58 additions and 54 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 =

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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