File: Xml001.hs

package info (click to toggle)
haskell-happstack-data 0.5.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 184 kB
  • sloc: haskell: 1,475; makefile: 2
file content (133 lines) | stat: -rw-r--r-- 5,259 bytes parent folder | download
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
123
124
125
126
127
128
129
130
131
132
133
{-# LANGUAGE TemplateHaskell, FlexibleInstances, MultiParamTypeClasses, FlexibleContexts, UndecidableInstances, DeriveDataTypeable #-}
module Happstack.Data.Tests.Xml001 (xml001, flexibleTests, flexibleManualTests, migrationTests) where

import Control.Monad.Identity
import Data.Generics.SYB.WithClass.Basics
import Data.Maybe
import Happstack.Data
import Test.HUnit (Test(..),(@?=),(~:))

$( deriveAll [''Eq, ''Default, ''Show]
    [d|
        data Bap = Zip | Zap
        data Fuzz a = Fo | Fig a
      |]
 )
$( deriveAll [''Eq, ''Show]
    [d|
        data Foo a = DefFoo | Foo a
        data Bar a = DefBar | Bar a

        data New = New Int
        data Old = Old YesNo
        data YesNo = Yes | No -- Use our own type as Bool has a
                              -- Xml special instance
      |]
 )

newtype MyList a = MkMyList { unMyList :: [a] }
    deriving (Show, Eq, Typeable)
instance (Sat (ctx (MyList a)), Sat (ctx [a]), Data ctx a)
      => Data ctx (MyList a) where
    gfoldl _ f z x  = z MkMyList `f` unMyList x
    toConstr _ (MkMyList _) = mkMyListConstr
    gunfold _ k z c  = case constrIndex c of
                           1 -> k (z MkMyList)
                           _ -> error "gunfold MyList: Can't happen"
    dataTypeOf _ _ = myListDataType
mkMyListConstr :: Constr
mkMyListConstr = mkConstr myListDataType "MkMyList" [] Prefix
myListDataType :: DataType
myListDataType = mkDataType "MyList" [mkMyListConstr]
instance Default a => Default (MyList a) where
    defaultValue = MkMyList defaultValue

instance Default New where
    defaultValue = New 7

instance Default Old where
    defaultValue = Old Yes

instance Xml New where
    version _ = Just "newver"
    otherVersion _ = Other (error "Other" :: Old)

instance Xml Old where
    typ _ = "New"

instance Migrate Old New where
    migrate (Old No)  = New 8
    migrate (Old Yes) = New 9

instance Default YesNo where
    defaultValue = No

instance Default a => Default (Foo a) where
    defaultValue = DefFoo

instance Default a => Default (Bar a) where
    defaultValue = DefBar

flexibleTests :: Test
flexibleTests =
    "flexibleTests" ~:
 [mkFTest [Elem "foo" [Elem "bar" [Elem "zap" []]]] (Foo $ Just $ Bar Zap)  @?= (Nothing :: Maybe Res)
 ,mkFTest [            Elem "bar" [Elem "zap" []] ] DefFoo                  @?= (Nothing :: Maybe Res)
 ,mkFTest [Elem "foo" [            Elem "zap" [] ]] (Foo Nothing)           @?= (Nothing :: Maybe Res)
 ,mkFTest [Elem "foo" [Elem "bar" [             ]]] (Foo $ Just $ Bar Zip)  @?= (Nothing :: Maybe Res)
 ,mkFTest [Elem "foo" [                          ]] (Foo Nothing)           @?= (Nothing :: Maybe Res)
 ,mkFTest [            Elem "bar" []              ] DefFoo                  @?= (Nothing :: Maybe Res)
 ,mkFTest [                        Elem "zap" []  ] DefFoo                  @?= (Nothing :: Maybe Res)
 ]

-- NOTE: these tests have never passed, they were broken from day one.
-- It is possible that MkMyList is supposed to be treated as
-- Transparent XML, like [] and (,) but it has never been implemented
-- that way.
-- 
-- We are disabling these tests until someone convinces us the tests
-- are right and the current implementation is wrong.
flexibleManualTests :: Test
flexibleManualTests =
    "flexibleManualTest" ~:
 [mkFTest [] (MkMyList [])                 @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "yes" []] (MkMyList [Yes]) @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "no"  []] (MkMyList [No])  @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "yes" [], Elem "yes" []] (MkMyList [Yes, Yes]) @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "yes" [], Elem "no"  []] (MkMyList [Yes, No])  @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "no"  [], Elem "yes" []] (MkMyList [No,  Yes]) @?= (Nothing :: Maybe (MyList YesNo))
 ,mkFTest [Elem "no"  [], Elem "no"  []] (MkMyList [No,  No])  @?= (Nothing :: Maybe (MyList YesNo))
 ]

migrationTests :: Test
migrationTests =
 "migrationTests" ~:
 [mkFTest [Elem "new" [testtype, newver, CData "5"       ]] (New 5) @?= Nothing
 ,mkFTest [Elem "old" [testtype, oldver, Elem  "yes"   []]] (New 9) @?= Nothing
 ,mkFTest [Elem "old" [testtype, oldver, Elem  "no"    []]] (New 8) @?= Nothing
 ,mkFTest [Elem "new" [                  CData "5"       ]] (New 5) @?= Nothing
 ,mkFTest [Elem "new" [                  Elem  "yes"   []]] (New 0) @?= Nothing
 ,mkFTest [Elem "new" [                                  ]] (New 0) @?= Nothing
 ,mkFTest [Elem "old" [testtype                          ]] (New 7) @?= Nothing
 ,mkFTest [Elem "old" [testtype, oldver                  ]] (New 8) @?= Nothing
 ,mkFTest [Elem "old" [                                  ]] (New 7) @?= Nothing
 ]

newver :: Element
newver = Attr versionAttr "newver"

oldver :: Element
oldver = Attr versionAttr "oldver"

testtype :: Element
testtype = Attr typeAttr (dataTypeName (dataTypeOf xmlProxy (undefined :: New)))

type Res = Foo (Maybe (Bar Bap))

mkFTest :: (Eq a, Xml a) => [Element] -> a -> Maybe a
mkFTest es v = case fromXml Flexible es of
                   Identity v' | v == v'   -> Nothing
                               | otherwise -> Just v'

xml001 :: Test
xml001 = "xml001" ~: [ flexibleTests, {- flexibleManualTests, -} migrationTests ]