Skip to content

Commit

Permalink
Add some tests, main app interface
Browse files Browse the repository at this point in the history
* Add command line arguments
* Write some rudimentary tests
  • Loading branch information
afnanenayet committed Nov 19, 2019
1 parent 0a78cd8 commit 760eac9
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 7 deletions.
36 changes: 34 additions & 2 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,6 1,38 @@
module Main where

import Lib
import Options.Applicative
import Data.Semigroup ( (<>) )

data CliFlags = CliFlags { inputFile :: String
, inPlace :: Bool
, configFile :: String
} deriving (Show, Eq)

-- | The parser for command line arguments, to be used with
-- optparse-applicative
cliParse :: Parser CliFlags
cliParse =
CliFlags
<$> strArgument (metavar "INPUT" <> help "The input filename")
<*> switch
( long "in-place"
<> short 'i'
<> help
"Whether to modify the file in-place (this is a destructive operation"
)
<*> strOption
(long "config" <> metavar "CONFIG" <> help "The config filename"
)


printFile :: CliFlags -> IO ()
printFile (CliFlags _ filename _) = print filename

main :: IO ()
main = someFunc
main = printFile =<< execParser opts
where
opts =
info (cliParse <**> helper)
$ fullDesc
<> progDesc "Format a markdown file"
<> header "mdfmt - a markdown formatter"
6 changes: 6 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 18,14 @@ extra-source-files:
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/afnanenayet/mdfmt#readme>
default-extensions: OverloadedStrings

dependencies:
- base >= 4.7 && < 5
- cmark
- optparse-applicative
- text
- word-wrap

library:
source-dirs: src
Expand All @@ -46,3 51,4 @@ tests:
- -with-rtsopts=-N
dependencies:
- mdfmt
- QuickCheck
26 changes: 22 additions & 4 deletions src/Lib.hs
Original file line number Diff line number Diff line change
@@ -1,6 1,24 @@
module Lib
( someFunc
) where
( wordWrap
, WordWrapError
)
where

someFunc :: IO ()
someFunc = putStrLn "someFunc"
import qualified Data.Text as T

-- | An error representing what can go wrong when performing a word wrap
data WordWrapError a = InvalidColumnWidth Int

-- | Word wrap some text to the desired column length
wordWrap :: T.Text -> Int -> Either (WordWrapError a) T.Text
wordWrap input width | width < 1 = Left $ InvalidColumnWidth width
| otherwise = Right $ T.intercalate "\n" wrappedLines
where
wrappedLines = map T.unwords $ gobble 0 [] $ T.words input
gobble :: Int -> [T.Text] -> [T.Text] -> [[T.Text]]
gobble _ acc [] = [reverse acc]
gobble k acc ws@(w : rest)
| 1 >= width = reverse acc : [w] : gobble 0 [] rest
| k 1 >= width = reverse acc : gobble 0 [] ws
| otherwise = gobble (k l 1) (w : acc) rest
where l = T.length w
12 changes: 12 additions & 0 deletions stack.yaml.lock
Original file line number Diff line number Diff line change
@@ -0,0 1,12 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files

packages: []
snapshots:
- completed:
size: 525663
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/14.yaml
sha256: 6edc48df46eb8bf7b861e98dd30d021a92c2e1820c9bb6528aac5d997b0e14ef
original: lts-14.14
31 changes: 30 additions & 1 deletion test/Spec.hs
Original file line number Diff line number Diff line change
@@ -1,2 1,31 @@
import Test.QuickCheck
import qualified Data.Text as T
import Data.Either
import Lib
import Text.Wrap

main :: IO ()
main = putStrLn "Test suite not yet implemented"
main = do
quickCheckWith stdArgs { maxSuccess = 100000 } prop_wordsAreWrapped

printWordWrap :: Show b => Either a b -> IO ()
printWordWrap (Left _ ) = print "error"
printWordWrap (Right text) = print text

prop_wordsAreWrapped :: [Char] -> Int -> Bool
prop_wordsAreWrapped slowString width
| length wrappedLines < 1 = True
| otherwise = maxLineSize <= expectedLineLength
where
input = T.pack slowString
result = wrapText
(WrapSettings { preserveIndentation = True, breakLongWords = False })
width
input
wrappedLines = T.lines result
maxLineSize = maximum $ map T.length wrappedLines
maxWordSize = maximum $ map T.length $ T.words input
-- if there is a word that's longer than the given width, then the
-- line will have to be as long as the longest word (at minimum)
expectedLineLength = max width (maxWordSize 1)

0 comments on commit 760eac9

Please sign in to comment.