packages feed

language-c-quote-0.3.1.2: tests/unit/Main.hs

{-# LANGUAGE CPP #-}
{-# LANGUAGE QuasiQuotes #-}

module Main where

import Test.HUnit

import Language.C.Quote.C
import System.Exit (exitFailure, exitSuccess)

#if !MIN_VERSION_template_haskell(2,7,0)
import qualified Data.Loc
import qualified Data.Symbol
import qualified Language.C.Syntax
#endif /* !MIN_VERSION_template_haskell(2,7,0) */

main = do
    count <- runTestTT tests
    case failures count of
      0 -> exitSuccess
      _ -> exitFailure

tests = TestList [exp_id, exp_int, exp_float, exp_char, exp_string,
                  exp_exp, exp_func, exp_args, exp_decl, exp_sdecl,
                  exp_enum, exp_edecl, exp_stm, exp_param, exp_ty,
                  pat_args, exp_hexp]


exp_id = "exp id" ~: [cexp|$id:ident|] ~?= [cexp|x|]
  where
    ident = "x"

exp_int =
    "exp int" ~:  [cexp|$int:one + $uint:one + $lint:one + $ulint:one|]
              ~?= [cexp|1 + 1U + 1L + 1UL|]
  where
    one = 1

exp_float =
    "exp float" ~:  [cexp|$float:one + $double:one + $ldouble:one|]
                ~?= [cexp|1.0F + 1.0 + 1.0L|]
  where
    one = 1

exp_char = "exp char" ~: [cexp|$char:a|] ~?=  [cexp|'a'|]
    where
      a = 'a'

exp_string =
    "exp string" ~: [cexp|$string:hello|] ~?=  [cexp|"Hello, world\n"|]
  where
    hello = "Hello, world\n"

exp_exp =
    "exp expression" ~: [cexp|$exp:e1 + $exp:e2|] ~?=  [cexp|1 + 2|]
  where
    e1 = [cexp|1|]
    e2 = [cexp|2|]

exp_func =
    "exp function" ~:  [cunit|$func:f|]
                   ~?= [cunit|int add(int x) { return x + 10; }|]
  where
    f = add 10
    add n = [cfun|int add(int x) { return x + $int:n; } |]

exp_args =
    "exp args" ~:  [cstm|f($exp:e1, $args:args, $exp:e2);|]
               ~?= [cstm|f(1, 1, 2, 2);|]
  where
    e1 = [cexp|1|]
    e2 = [cexp|2|]
    args = [e1, e2]

exp_decl =
    "exp decl" ~:  [cfun|int inc(int n) {
                             $decl:d1;
                             $decls:decls

                             return n + 1;
                          }|]
               ~?= [cfun|int inc(int n) {
                             int i;
                             int j;
                             char c = 'c';

                             return n + 1;
                          }|]
  where
    d1 = [cdecl|int i;|]
    d2 = [cdecl|int j;|]
    d3 = [cdecl|char c = 'c';|]
    decls = [d2, d3]

exp_sdecl =
    "exp sdecl" ~:  [cty|struct foo { $sdecl:d1 $sdecls:decls }|]
                ~?= [cty|struct foo { int i; int j; char c; }|]
  where
    d1 = [csdecl|int i;|]
    d2 = [csdecl|int j;|]
    d3 = [csdecl|char c;|]
    decls = [d2, d3]

exp_enum = "exp enum" ~:  [cty|enum foo { $enum:enum1, $enums:enums }|]
                      ~?= [cty|enum foo { A = 0, B, C = 2 }|]
  where
    enum1 = [cenum|A = 0|]
    enum2 = [cenum|B|]
    enum3 = [cenum|C = 2|]
    enums = [enum2, enum3]

exp_edecl =
    "exp edecl" ~:  [cunit|$edecl:d1 $edecls:decls|]
                ~?= [cunit|int i; int j; char c = 'c';|]
  where
    d1 = [cedecl|int i;|]
    d2 = [cedecl|int j;|]
    d3 = [cedecl|char c = 'c';|]
    decls = [d2, d3]

exp_stm =
    "exp stm" ~:  [cfun|int add(int x) { $stms:stms return x + 1; }|]
              ~?= [cfun|int add(int x) { a = 1; b = 2; return x + 1; }|]
  where
    one = 1
    stm1 = [cstm|a = $int:one;|]
    stm2 = [cstm|b = 2;|]
    stms = [stm1, stm2]

exp_param =
    "exp param" ~:  [cdecl|int f($param:ty1, $params:tys);|]
                ~?= [cdecl|int f(char, int, float);|]
  where
    ty1 = [cparam|char|]
    ty2 = [cparam|int|]
    ty3 = [cparam|float|]
    tys = [ty2, ty3]

exp_ty =
    "exp ty" ~:  [cdecl|$ty:ty1 f(const $ty:ty2);|]
             ~?= [cdecl|int f(const float);|]
  where
    ty1 = [cty|int|]
    ty2 = [cty|float|]

pat_args =
    "pat args" ~:   stms
               ~?=  [[cexp|2|], [cexp|3|]]
  where
    stms = case [cstm|f(1, 2, 3);|] of
             [cstm|f(1, $args:es);|] -> es
             _ -> []

exp_hexp =
    "exp hexp" ~:  [cexp|$ulint:(13 - 2*5)|]
               ~?= [cexp|3UL|]