• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

matzefriedrich / parsley / 25522066949

07 May 2026 09:05PM UTC coverage: 79.735% (-1.1%) from 80.83%
25522066949

Pull #82

github

matzefriedrich
Updates the changelog
Pull Request #82: Support context.Context and error in activator signatures

78 of 88 new or added lines in 6 files covered. (88.64%)

56 existing lines in 5 files now uncovered.

2046 of 2566 relevant lines covered (79.73%)

31.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.51
/internal/core/function_info.go
1
package core
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "reflect"
8
        "runtime"
9
        "strings"
10

11
        "github.com/matzefriedrich/parsley/pkg/types"
12
)
13

14
const (
15
        ErrorNotAFunction                            = "not a function"
16
        ErrorReturnTypeHasToHaveExactlyOnReturnValue = "return type has to have exactly one return value"
17
        ErrorSecondReturnTypeIsNotErr                = "second return type is not an error type"
18
)
19

20
var (
21
        ErrNotAFunction                            = errors.New(ErrorNotAFunction)
22
        ErrReturnTypeHasToHaveExactlyOnReturnValue = errors.New(ErrorReturnTypeHasToHaveExactlyOnReturnValue)
23
)
24

25
type functionInfo struct {
26
        reflectedFunctionValue reflect.Value
27
        funcType               reflect.Type
28
        returnType             types.ServiceType
29
        parameters             []types.FunctionParameterInfo
30
        hasErrorReturn         bool
31
        hasContextParameter    bool
32
}
33

34
var _ types.FunctionInfo = &functionInfo{}
35

UNCOV
36
type functionParameterInfo struct {
×
UNCOV
37
        parameterType types.ServiceType
×
UNCOV
38
}
×
UNCOV
39

×
40
// String returns the string representation of the reflected type of the function parameter.
41
func (f functionParameterInfo) String() string {
6✔
42
        reflectedType := f.Type().ReflectedType()
6✔
43
        return reflectedType.String()
6✔
44
}
6✔
45

46
// Type returns the ServiceType of the function parameter, which provides meta information like name, package path, and reflect type.
47
func (f functionParameterInfo) Type() types.ServiceType {
115✔
48
        return f.parameterType
115✔
49
}
115✔
50

UNCOV
51
var _ types.FunctionParameterInfo = &functionParameterInfo{}
×
UNCOV
52

×
UNCOV
53
// ReflectFunctionInfoFrom retrieves metadata about a given function using reflection, providing details about the function's type,
×
UNCOV
54
// return type, parameter types, and other characteristics. Ensures that the value provided is a valid function and returns
×
UNCOV
55
// appropriate errors if it is not. Useful for dynamically inspecting and working with functions.
×
56
func ReflectFunctionInfoFrom(value reflect.Value) (types.FunctionInfo, error) {
171✔
57
        funcType := value.Type()
171✔
58
        if funcType.Kind() != reflect.Func {
172✔
59
                return nil, types.NewReflectionError(ErrorNotAFunction)
1✔
60
        }
1✔
61
        rt, hasError, err := returnType(funcType)
170✔
62
        if err != nil {
171✔
63
                return nil, err
1✔
64
        }
1✔
65
        parameters := parameterInfos(funcType)
169✔
66
        hasContext := false
169✔
67
        if len(parameters) > 0 {
221✔
68
                firstParamType := parameters[0].Type().ReflectedType()
52✔
69
                contextType := reflect.TypeOf((*context.Context)(nil)).Elem()
52✔
70
                if firstParamType.Implements(contextType) {
62✔
71
                        hasContext = true
10✔
72
                }
10✔
NEW
73
        }
×
74
        return &functionInfo{
169✔
75
                reflectedFunctionValue: value,
169✔
76
                funcType:               funcType,
169✔
77
                returnType:             rt,
169✔
78
                parameters:             parameters,
169✔
79
                hasErrorReturn:         hasError,
169✔
80
                hasContextParameter:    hasContext,
169✔
81
        }, nil
169✔
UNCOV
82
}
×
83

UNCOV
84
// Name retrieves the name of the reflected function.
×
85
func (f functionInfo) Name() string {
10✔
86
        pointer := f.reflectedFunctionValue.Pointer()
10✔
87
        functionFromPointer := runtime.FuncForPC(pointer)
10✔
88
        if functionFromPointer != nil {
20✔
89
                return functionFromPointer.Name()
10✔
90
        }
10✔
91
        return ""
×
92
}
UNCOV
93

×
NEW
94
// Parameters Returns a slice of FunctionParameterInfo representing the parameters of the function.
×
95
func (f functionInfo) Parameters() []types.FunctionParameterInfo {
5✔
96
        return f.parameters
5✔
97
}
5✔
UNCOV
98

×
99
func (f functionInfo) ParameterTypes() []types.ServiceType {
161✔
100
        parameterTypes := make([]types.ServiceType, len(f.parameters))
161✔
101
        for i, parameter := range f.parameters {
218✔
102
                parameterTypes[i] = parameter.Type()
57✔
103
        }
57✔
104
        return parameterTypes
161✔
UNCOV
105
}
×
106

107
func (f functionInfo) HasErrorReturn() bool {
165✔
108
        return f.hasErrorReturn
165✔
109
}
165✔
NEW
110

×
111
func (f functionInfo) ExpectsContextParameter() bool {
164✔
112
        return f.hasContextParameter
164✔
113
}
164✔
NEW
114

×
115
// ReturnType returns the type of the service returned by the function.
116
func (f functionInfo) ReturnType() types.ServiceType {
166✔
117
        return f.returnType
166✔
118
}
166✔
UNCOV
119

×
UNCOV
120
// String returns a string representation of the function's signature, including its name, parameters, and return type.
×
121
func (f functionInfo) String() string {
7✔
122
        parameterTypeNames := make([]string, len(f.parameters))
7✔
123
        for i, t := range f.parameters {
13✔
124
                parameterTypeNames[i] = t.String()
6✔
125
        }
6✔
126
        reflectedReturnType := f.returnType.ReflectedType()
7✔
127
        funcTypeName := reflectedReturnType.String()
7✔
128
        return fmt.Sprintf("%s(%s) %s", f.Name(), strings.Join(parameterTypeNames, ","), funcTypeName)
7✔
129
}
130

131
func returnType(funcType reflect.Type) (types.ServiceType, bool, error) {
170✔
132
        numReturnValues := funcType.NumOut()
170✔
133
        const (
170✔
134
                serviceTypeIndex = 0
170✔
135
                errorTypeIndex   = 1
170✔
136
        )
170✔
137
        if numReturnValues == 1 {
333✔
138
                serviceType := funcType.Out(serviceTypeIndex)
163✔
139
                return types.ServiceTypeFrom(serviceType), false, nil
163✔
140
        }
163✔
141
        if numReturnValues == 2 {
13✔
142
                serviceType := funcType.Out(serviceTypeIndex)
6✔
143
                errorType := funcType.Out(errorTypeIndex)
6✔
144
                if isErrorType(errorType) {
12✔
145
                        return types.ServiceTypeFrom(serviceType), true, nil
6✔
146
                }
6✔
NEW
147
                return nil, false, types.NewReflectionError(ErrorSecondReturnTypeIsNotErr)
×
148
        }
149
        return nil, false, types.NewReflectionError(ErrorReturnTypeHasToHaveExactlyOnReturnValue)
1✔
150
}
151

152
func parameterInfos(funcType reflect.Type) []types.FunctionParameterInfo {
169✔
153
        parameters := make([]types.FunctionParameterInfo, 0)
169✔
154
        numParameters := funcType.NumIn()
169✔
155
        for i := 0; i < numParameters; i++ {
232✔
156
                parameterType := funcType.In(i)
63✔
157
                serviceType := types.ServiceTypeFrom(parameterType)
63✔
158
                p := functionParameterInfo{
63✔
159
                        parameterType: serviceType,
63✔
160
                }
63✔
161
                parameters = append(parameters, p)
63✔
162
        }
63✔
163
        return parameters
169✔
164
}
165

166
func isErrorType(t reflect.Type) bool {
6✔
167
        errorType := reflect.TypeOf((*error)(nil))
6✔
168
        return t.Implements(errorType.Elem())
6✔
169
}
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc