###############################################################################
###############################################################################
###############################################################################
#group type signatures
###############################################################################
###############################################################################
###############################################################################

#test simple001
func :: a -> a

#test long typeVar
func
  :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
  -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd

#test keep linebreak mode
func
  :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
  -> lakjsdlkjasldkj
  -> lakjsdlkjasldkj

#test simple parens 1
func :: ((a))

#test simple parens 2
func :: (a -> a) -> a

#test simple parens 3
func :: a -> (a -> a)

#test did anyone say parentheses?
func :: (((((((((())))))))))

-- current output is.. funny. wonder if that can/needs to be improved..
#test give me more!
#pending
func :: ((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))

#test unit
func :: ()


###############################################################################

#test paren'd func 1
func
  :: (  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     -> lakjsdlkjasldkj
     -> lakjsdlkjasldkj
     )

#test paren'd func 2
func
  :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
  -> (lakjsdlkjasldkj -> lakjsdlkjasldkj)

#test paren'd func 3
func
  :: (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd -> lakjsdlkjasldkj)
  -> lakjsdlkjasldkj

#test paren'd func 4
func
  :: (  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     )
  -> lakjsdlkjasldkj

#test paren'd func 5
func
  :: ( (  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       )
     )

###############################################################################

#test type application 1
func :: asd -> Either a b

#test type application 2
func
  :: asd
  -> Either
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd

#test type application 3
func
  :: asd
  -> Trither
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd

#test type application 4
func
  :: Trither
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
  -> asd

#test type application 5
func
  :: Trither
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd -> asd)

#test type application 6
func
  :: Trither
       asd
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       (  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       )

#test type application paren 1
func
  :: asd
  -> ( Trither
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     )

#test type application paren 2
func
  :: asd
  -> ( Trither
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     )
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd

#test type application paren 3
func
  :: ( Trither
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
         lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     )
       lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
  -> asd

###############################################################################

#test list simple
func :: [a -> b]

#test list func
func
  :: [  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     ]

#test list paren
func
  :: [ (  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       )
     ]

################################################################## -- #############

#test tuple type 1
func :: (a, b, c)

#test tuple type 2
func :: ((a, b, c), (a, b, c), (a, b, c))

#test tuple type long
func
  :: ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
     )

#test tuple type nested
func
  :: ( ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       , (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd)
       , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       )
     )

#test tuple type function
func
  :: [ ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
       )
     ]
###############################################################################
#test type operator stuff
#pending
test050 :: a :+: b
test051 ::  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
        :+: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
test052 ::  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
        ->  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
        :+: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd
        ->  lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd

###############################################################################

#test forall oneliner
{-# LANGUAGE ScopedTypeVariables #-}
func :: forall (a :: *) b . a -> b

#test forall context multiline
{-# LANGUAGE ScopedTypeVariables #-}
func
  :: forall m
   . Foo
  => ColMap2
  -> ColInfo
  -> ColInfo
  -> ColInfo
  -> ColInfo
  -> m ()

#test forall no-context multiline
{-# LANGUAGE ScopedTypeVariables #-}
func
  :: forall m
   . ColMap2
  -> ColInfo
  -> ColInfo
  -> ColInfo
  -> ColInfo
  -> ColInfo
  -> m ()

#test language pragma issue
{-# LANGUAGE ScopedTypeVariables #-}
func :: forall (a :: *) b . a -> b

#test comments 1
func :: a -> b -- comment

#test comments 2
funcA :: a -> b -- comment A
funcB :: a -> b -- comment B

#test comments all
#pending
-- a
func -- b
  :: -- c
  a -- d
  -> -- e
  ( -- f
  c -- g
  , -- h
  d -- i
  ) -- j
-- k


###############################################################################
###############################################################################
###############################################################################
#group type signatures pragmas
###############################################################################
###############################################################################
###############################################################################

#test inline pragma 1
func = f
 where
  {-# INLINE f #-}
  f = id

#test inline pragma 2
func = ($)
 where
  {-# INLINE ($) #-}
  ($) = id

#test inline pragma 3
func = f
 where
  {-# INLINE CONLIKE [1] f #-}
  f = id

#test inline pragma 4
#pending this does not work with the compiler version we currently use yet (i think). should work with ghc-8.0.2.
func = f
 where
  {-# INLINE [~] f #-}
  f = id


###############################################################################
###############################################################################
###############################################################################
#group equation.basic
###############################################################################
###############################################################################
###############################################################################
## some basic testing of different kinds of equations.
## some focus on column layouting for multiple-equation definitions.
## (that part probably is not implemented in any way yet.)

#test basic 1
func x = x

#test infix 1
x *** y = x

#test symbol prefix
(***) x y = x


###############################################################################
###############################################################################
###############################################################################
#group equation.patterns
###############################################################################
###############################################################################
###############################################################################

#test wildcard
func _ = x

#test simple long pattern
#pending
func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable
  = x

#test simple multiline pattern
#pending
func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable
     reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable
  = x

#test another multiline pattern
#pending
func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable
     a
     b
  = x

#test simple constructor
func (A a) = a

#test list constructor
func (x:xr) = x

#test some other constructor symbol
#pending
func (x:+:xr) = x


###############################################################################
###############################################################################
###############################################################################
#group equation.guards
###############################################################################
###############################################################################
###############################################################################
#test simple guard
func | True = x

#test multiple-clauses-1
func x | x         = simple expression
       | otherwise = 0

#test multiple-clauses-2
func x
  | a somewhat longer guard x = "and a somewhat longer expession that does not"
  | otherwise                 = "fit without putting the guards in new lines"

#test multiple-clauses-3
func x
  | very long guard, another rather long guard that refers to x = nontrivial
    expression
    foo
    bar
    alsdkjlasdjlasj
  | otherwise = 0

#test multiple-clauses-4
func x
  | very long guard, another rather long guard that refers to x
  = nontrivialexpression foo bar alsdkjlasdjlasj
  | otherwise
  = 0

#test multiple-clauses-5
func x
  | very loooooooooooooooooooooooooooooong guard
  , another rather long guard that refers to x
  = nontrivial expression foo bar alsdkjlasdjlasj
  | otherwise
  = 0


###############################################################################
###############################################################################
###############################################################################
#group expression.basic
###############################################################################
###############################################################################
###############################################################################

#test var
func = x

describe "infix op" $ do
#test 1
func = x + x

#test long
#pending
func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj
     + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj

#test long keep linemode 1
#pending
func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj
     + mweroiuxlskdfjlksj
     + mweroiuxlskdfjlksj

#test long keep linemode 2
#pending
func = mweroiuxlskdfjlksj
     + mweroiuxlskdfjlksj
     + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj

#test literals
func = 1
func = "abc"
func = 1.1e5
func = 'x'
func = 981409823458910394810928414192837123987123987123

#test lambda
func = \x -> abc

describe "app" $ do
#test 1
func = klajsdas klajsdas klajsdas

#test 2
func = lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
  lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
  lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd

#test 3
func = lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd lakjsdlajsdljas
                                                     lakjsdlajsdljas
                                                     lakjsdlajsdljas

###
#group expression.basic.sections
###

#test left
func = (1 +)

#test right
func = (+ 1)

#test left inf
func = (1 `abc`)

#test right inf
func = (`abc` 1)

###
#group tuples
###

#test pair
func = (abc, def)

#test pair section left
func = (abc, )

#test pair section right
func = (, abc)

#test quintuple section long
myTupleSection =
  ( verylaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaargefirstelement
  ,
  , verylaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaargethirdelement
  ,
  )

#test 2
#pending
func = (lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
  , lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd)



###############################################################################
###############################################################################
###############################################################################
#group expression.do statements
###############################################################################
###############################################################################
###############################################################################

#test simple
func = do
  stmt
  stmt

#test bind
func = do
  x <- stmt
  stmt x

#test let
func = do
  let x = 13
  stmt x


###############################################################################
###############################################################################
###############################################################################
#group expression.lists
###############################################################################
###############################################################################
###############################################################################

#test monad-comprehension-case-of
func =
  foooooo
    $ [ case
          foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
        of
          _ -> True
      ]


###############################################################################
###############################################################################
###############################################################################
#group stylisticspecialcases
###############################################################################
###############################################################################
###############################################################################

#test operatorprefixalignment-even-with-multiline-alignbreak
func =
  foo
    $  [ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
       , bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
       ]
    ++ [ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc]