summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wales <mark@smallhadroncollider.com>2018-11-23 11:11:46 +0000
committerMark Wales <mark@smallhadroncollider.com>2018-11-23 11:11:46 +0000
commit789bccdf4fa04dc6c234159196678ea122c05db4 (patch)
tree953117685a8d2c2a2e4775aaef9ce27924117e0b
parentede4c750ab471de3a391c2dcae6fb43ceca8cced (diff)
feat (UI.TextEdit): started working on new TextEdit modulefeature/line-breaks
-rw-r--r--package.yaml3
-rw-r--r--src/UI/TextEdit.hs45
-rw-r--r--test/UI/TextEditTest.hs93
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")
+ )
+ ]
+ ]
+ ]