diff options
author | Mark Wales <mark@smallhadroncollider.com> | 2018-11-23 11:11:46 +0000 |
---|---|---|
committer | Mark Wales <mark@smallhadroncollider.com> | 2018-11-23 11:11:46 +0000 |
commit | 789bccdf4fa04dc6c234159196678ea122c05db4 (patch) | |
tree | 953117685a8d2c2a2e4775aaef9ce27924117e0b | |
parent | ede4c750ab471de3a391c2dcae6fb43ceca8cced (diff) |
feat (UI.TextEdit): started working on new TextEdit modulefeature/line-breaks
-rw-r--r-- | package.yaml | 3 | ||||
-rw-r--r-- | src/UI/TextEdit.hs | 45 | ||||
-rw-r--r-- | test/UI/TextEditTest.hs | 93 |
3 files changed, 141 insertions, 0 deletions
diff --git a/package.yaml b/package.yaml index a7d6fd8..27e5fee 100644 --- a/package.yaml +++ b/package.yaml @@ -46,6 +46,7 @@ library: - IO.HTTP.Trello.List - IO.HTTP.Trello.ChecklistItem - UI.Field + - UI.TextEdit dependencies: - base <=5 @@ -92,10 +93,12 @@ tests: - containers - file-embed - lens + - quickcheck-instances - taskell - tasty - tasty-discover - tasty-expected-failure - tasty-hunit + - tasty-quickcheck - text - time diff --git a/src/UI/TextEdit.hs b/src/UI/TextEdit.hs new file mode 100644 index 0000000..2b2e1fc --- /dev/null +++ b/src/UI/TextEdit.hs @@ -0,0 +1,45 @@ +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE OverloadedStrings #-} +module UI.TextEdit ( + textEdit + , getText + , getCursor + , getWrapped +) where + +import ClassyPrelude hiding (lines) + +import Data.Text (splitOn) + +type Cursor = (Int, Int) +type Lines = [Text] + +data TextEdit = TextEdit Lines Cursor + +textEdit :: Text -> TextEdit +textEdit text = TextEdit lines (x, y) + where lines = splitOn "\n" text + y = length lines - 1 + x = maybe 0 length (lastMay lines) + +getText :: TextEdit -> Text +getText (TextEdit lines _) = intercalate "\n" lines + +getCursor :: TextEdit -> Cursor +getCursor (TextEdit _ cursor) = cursor + +getWrapped :: Int -> TextEdit -> ([Text], Cursor) +getWrapped _ (TextEdit lines cursor) = (split =<< lines, cursor) + +appendToLast :: Char -> [Text] -> [Text] +appendToLast char parts = case fromNullable parts of + Just parts' -> init parts' ++ [snoc (last parts') char] + Nothing -> [singleton char] + +pullSpaces :: [Text] -> Char -> [Text] +pullSpaces parts char + | char == ' ' = parts ++ [" "] ++ [""] + | otherwise = appendToLast char parts + +split :: Text -> [Text] +split = foldl' pullSpaces [] diff --git a/test/UI/TextEditTest.hs b/test/UI/TextEditTest.hs new file mode 100644 index 0000000..6bd89a1 --- /dev/null +++ b/test/UI/TextEditTest.hs @@ -0,0 +1,93 @@ +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE OverloadedStrings #-} +module UI.TextEditTest ( + test_textEdit +) where + +import ClassyPrelude + +import Test.Tasty +import Test.Tasty.HUnit +import Test.Tasty.QuickCheck +import Test.QuickCheck.Instances.Text () + +import UI.TextEdit + +test_textEdit :: TestTree +test_textEdit = + testGroup "UI.TextEdit" [ + testGroup "Setting then getting" [ + testCase "Basic string" ( + assertEqual + "Should return same string" + "Blah" + (getText $ textEdit "Blah") + ) + + , testCase "New lines" ( + assertEqual + "Should return same string" + "Fish\nCow\nMonkey" + (getText $ textEdit "Fish\nCow\nMonkey") + ) + + , testProperty "Any string" $ \s -> getText (textEdit s) == s + ] + + , testGroup "Cursor Positioning" [ + testCase "Basic string" ( + assertEqual + "Should be at end of string" + (4, 0) + (getCursor $ textEdit "Blah") + ) + + , testCase "New lines" ( + assertEqual + "Should be at end of string" + (6, 2) + (getCursor $ textEdit "Fish\nCow\nMonkey") + ) + + , testCase "New line at end" ( + assertEqual + "Should be at end of string" + (0, 3) + (getCursor $ textEdit "Fish\nCow\nMonkey\n") + ) + ] + + , testGroup "Wrapped Cursor Positioning" [ + testGroup "No wrapping necessary" [ + testCase "Basic string" ( + assertEqual + "Should be at end of string" + (["Blah"], (4, 0)) + (getWrapped 30 $ textEdit "Blah") + ) + + , testCase "New lines" ( + assertEqual + "Should be at end of string" + (["Fish", "Cow", "Monkey"], (6, 2)) + (getWrapped 30 $ textEdit "Fish\nCow\nMonkey") + ) + + , testCase "New line at end" ( + assertEqual + "Should be at end of string" + (["Fish", "Cow", "Monkey", ""], (0, 3)) + (getWrapped 30 $ textEdit "Fish\nCow\nMonkey\n") + ) + ] + + , testGroup "Wrapping necessary" [ + testCase "Basic string" ( + assertEqual + "Should be at end of string" + (["Blah blah ", "blah"], (4, 1)) + (getWrapped 10 $ textEdit "Blah blah blah") + ) + ] + ] + ] |