File: ModuleTests.hs

package info (click to toggle)
haskell-hslua-packaging 2.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 160 kB
  • sloc: haskell: 1,296; makefile: 5
file content (145 lines) | stat: -rw-r--r-- 4,370 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
134
135
136
137
138
139
140
141
142
143
144
145
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-|
Module      : HsLua.Packaging.ModuleTests
Copyright   : © 2019-2024 Albert Krewinkel
License     : MIT
Maintainer  : Albert Krewinkel <tarleb@hslua.org>
Stability   : alpha
Portability : Requires GHC 8 or later.

Tests creating and loading of modules with Haskell.
-}
module HsLua.Packaging.ModuleTests (tests) where

import HsLua.Core
import HsLua.Marshalling
  ( forcePeek, peekFieldRaw, peekIntegral, peekList, peekName, peekString
  , pushIntegral, pushText)
import HsLua.Packaging.Documentation
import HsLua.Packaging.Function
import HsLua.Packaging.Module
import HsLua.Packaging.UDType (deftype, initType)
import Test.Tasty.HsLua ((=:), shouldBeResultOf)
import Test.Tasty (TestTree, testGroup)

import qualified HsLua.Core as Lua

-- | Specifications for Attributes parsing functions.
tests :: TestTree
tests = testGroup "Module"
  [ testGroup "creation helpers"
    [ "create produces a table" =:
      Lua.TypeTable `shouldBeResultOf` do
        Lua.newtable
        Lua.ltype Lua.top
    ]
  , testGroup "module type"
    [ "register module" =:
      1 `shouldBeResultOf` do
        Lua.openlibs
        old <- Lua.gettop
        registerModule mymath
        new <- Lua.gettop
        return (new - old)

    , "call module function" =:
      24 `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        _ <- Lua.dostring $ mconcat
             [ "local mymath = require 'mymath'\n"
             , "return mymath.factorial(4)"
             ]
        forcePeek $ peekIntegral @Prelude.Integer Lua.top

    , "call module as function" =:
      "call me maybe" `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        _ <- Lua.dostring "return (require 'mymath')()"
        forcePeek $ peekString Lua.top

    , "access name in docs" =:
      "mymath" `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        TypeTable <- getdocumentation top
        forcePeek $ peekFieldRaw peekString "name" Lua.top

    , "first function name in docs" =:
      "factorial" `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        TypeTable <- getdocumentation top
        TypeTable <- getfield top "functions"
        TypeTable <- rawgeti top 1
        forcePeek $ peekFieldRaw peekString "name" Lua.top

    , "function doc is shared" =:
      True `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        pushvalue top
        setglobal "mymath"
        -- get doc table via module docs
        TypeTable <- getdocumentation top
        TypeTable <- getfield top "functions"
        TypeTable <- rawgeti top 1
        -- get doc table via function
        OK <- dostring "return mymath.factorial"
        TypeTable <- getdocumentation top
        -- must be the same
        rawequal (nth 1) (nth 3)

    , "first field name in docs" =:
      "unit" `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        TypeTable <- getdocumentation top
        TypeTable <- getfield top "fields"
        TypeTable <- rawgeti top 1
        forcePeek $ peekFieldRaw peekString "name" Lua.top

    , "document object has associated types" =:
      ["Void"] `shouldBeResultOf` do
        Lua.openlibs
        registerModule mymath
        TypeTable <- getdocumentation top
        TypeFunction <- getfield top "types"
        call 0 1
        forcePeek $ peekList peekName top
    ]
  ]

mymath :: Module Lua.Exception
mymath = Module
  { moduleName = "mymath"
  , moduleDescription = "A math module."
  , moduleFields = [
      Field "unit" "integer" "additive unit" (pushinteger 1)
    ]
  , moduleFunctions = [factorial]
  , moduleOperations =
    [ (,) Call $ lambda
      ### (1 <$ pushText "call me maybe")
      =?> "call result"
    ]
  , moduleTypeInitializers = [initType (deftype "Void" [] [])]
  }

factorial :: DocumentedFunction Lua.Exception
factorial =
  defun "factorial"
  ### liftPure (\n -> product [1..n])
  <#> factorialParam
  =#> factorialResult

factorialParam :: Parameter Lua.Exception Prelude.Integer
factorialParam =
  parameter peekIntegral "integer"
    "n"
    "number for which the factorial is computed"

factorialResult :: FunctionResults Lua.Exception Prelude.Integer
factorialResult = functionResult pushIntegral "integer" "factorial"