~jaro/balkon

ref: 5a30ef49d1c4a7f8a77425c67a5ee8e5e8243c8e balkon/test/Data/Text/ParagraphLayout/Internal/TextContainerSpec.hs -rw-r--r-- 4.8 KiB
5a30ef49 — Adrian Cochrane Loosen dependency bounds. 1 year, 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
module Data.Text.ParagraphLayout.Internal.TextContainerSpec (spec) where

import Data.Text (Text, empty, pack)
import Data.Text.Foreign (lengthWord8)

import Test.Hspec
import Data.Text.ParagraphLayout.Internal.TextContainer

data ExampleContainer = Contain { cText :: Text, cOffset :: Int }
    deriving (Show, Eq)

contain :: String -> Int -> ExampleContainer
contain s o = Contain (pack s) o

instance TextContainer ExampleContainer where
    getText = cText

instance SeparableTextContainer ExampleContainer where
    splitTextAt8 n (Contain t o) = (Contain t1 o1, Contain t2 o2)
        where
            (t1, t2) = splitTextAt8 n t
            o1 = o
            o2 = o + lengthWord8 t1
    dropWhileEnd p (Contain t o) = Contain (dropWhileEnd p t) o

exampleContainers :: [ExampleContainer]
exampleContainers = [c1, c2]
    where
        (c1, c2) = splitTextAt8 11 $ contain "Vikipedija (Википедија)" 10

exampleBreaks :: [Int]
exampleBreaks =
    [
    -- Out of bounds. Should not generate any splits.
    999, 50,
    -- End of last text. Should not generate a split.
    43,
    -- Word and syllable bounds in the second text,
    -- similar to hyphenation rules. Each should generate a corresponding split.
    38, 34, 30, 26,
    -- The exact edge between the two texts.
    -- Should generate a split, but not any empty containers.
    21,
    -- Word and syllable bounds in the first text.
    -- Each should generate a corresponding split.
    18, 16, 14, 12,
    -- Start of first text. Should not generate a split.
    10,
    -- Out of bounds. Should not generate any splits.
    5, 0, -1
    ]

exampleBreakPoints :: ExampleContainer -> [Int]
exampleBreakPoints c =
    dropWhile (>= l) $ takeWhile (>= 0) $ map (subtract d) $ exampleBreaks
    where
        l = lengthWord8 $ cText c
        d = cOffset c

isSpace :: Char -> Bool
isSpace = (==' ')

spec :: Spec
spec = do
    describe "splitTextsBy" $ do
        it "splits example text containers" $ do
            splitTextsBy exampleBreakPoints exampleContainers `shouldBe`
                [ ( [ contain "Vikipedija " 10, contain "(Википеди" 21 ]
                  , [ contain "ја)" 38 ]
                  )
                , ( [ contain "Vikipedija " 10, contain "(Википе" 21 ]
                  , [ contain "дија)" 34 ]
                  )
                , ( [ contain "Vikipedija " 10, contain "(Вики" 21 ]
                  , [ contain "педија)" 30 ]
                  )
                , ( [ contain "Vikipedija " 10, contain "(Ви" 21 ]
                  , [ contain "кипедија)" 26 ]
                  )
                , ( [ contain "Vikipedija " 10 ]
                  , [ contain "(Википедија)" 21 ]
                  )
                , ( [ contain "Vikipedi" 10 ]
                  , [ contain "ja " 18, contain "(Википедија)" 21 ]
                  )
                , ( [ contain "Vikipe" 10 ]
                  , [ contain "dija " 16, contain "(Википедија)" 21 ]
                  )
                , ( [ contain "Viki" 10 ]
                  , [ contain "pedija " 14, contain "(Википедија)" 21 ]
                  )
                , ( [ contain "Vi" 10 ]
                  , [ contain "kipedija " 12, contain "(Википедија)" 21 ]
                  )
                ]
    describe "trimTextsEnd" $ do
        describe "isSpace" $ do
            it "does nothing on an empty list" $ do
                let inputTexts = [] :: [Text]
                trimTextsEnd isSpace inputTexts `shouldBe` inputTexts
            it "does nothing when last run does not end with space" $ do
                let inputTexts = [pack "some ", pack "text"]
                trimTextsEnd isSpace inputTexts `shouldBe` inputTexts
            it "trims empty texts down to an empty list" $ do
                let inputTexts = [empty, empty, empty]
                trimTextsEnd isSpace inputTexts `shouldBe` []
            it "trims empty texts from a list" $ do
                let inputTexts = [pack "some ", pack "text", empty, empty]
                trimTextsEnd isSpace inputTexts `shouldBe`
                    [pack "some ", pack "text"]
            it "trims spaces from last text" $ do
                let inputTexts = [pack "some ", pack "text      "]
                trimTextsEnd isSpace inputTexts `shouldBe`
                    [pack "some ", pack "text"]
            it "trims texts containing only spaces" $ do
                let inputTexts = [pack "some ", pack "text", pack "    "]
                trimTextsEnd isSpace inputTexts `shouldBe`
                    [pack "some ", pack "text"]
            it "trims last text that contains non-spaces" $ do
                let inputTexts = [pack "some ", pack "text  ", pack "    "]
                trimTextsEnd isSpace inputTexts `shouldBe`
                    [pack "some ", pack "text"]