github.com/expr-lang/expr@v1.16.9/docgen/docgen_test.go (about) 1 package docgen_test 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 8 "github.com/expr-lang/expr/internal/testify/assert" 9 "github.com/expr-lang/expr/internal/testify/require" 10 11 . "github.com/expr-lang/expr/docgen" 12 ) 13 14 type Tweet struct { 15 Size int 16 Message string 17 } 18 19 type Env struct { 20 Tweets []Tweet 21 Config struct { 22 MaxSize int32 23 } 24 Env map[string]any 25 // NOTE: conflicting type name 26 TimeWeekday time.Weekday 27 Weekday Weekday 28 } 29 30 type Weekday int 31 32 func (Weekday) String() string { 33 return "" 34 } 35 36 type Duration int 37 38 func (Duration) String() string { 39 return "" 40 } 41 42 func (*Env) Duration(s string) Duration { 43 return Duration(0) 44 } 45 46 func TestCreateDoc(t *testing.T) { 47 Operators = nil 48 Builtins = nil 49 doc := CreateDoc(&Env{}) 50 expected := &Context{ 51 Variables: map[Identifier]*Type{ 52 "Tweets": { 53 Kind: "array", 54 Type: &Type{ 55 Kind: "struct", 56 Name: "Tweet", 57 }, 58 }, 59 "Config": { 60 Kind: "struct", 61 Fields: map[Identifier]*Type{ 62 "MaxSize": {Kind: "int"}, 63 }, 64 }, 65 "Env": { 66 Kind: "map", 67 Key: &Type{Kind: "string"}, 68 Type: &Type{Kind: "any"}, 69 }, 70 "Duration": { 71 Kind: "func", 72 Arguments: []*Type{ 73 {Kind: "string"}, 74 }, 75 Return: &Type{Kind: "struct", Name: "Duration"}, 76 }, 77 "TimeWeekday": { 78 Name: "time.Weekday", 79 Kind: "struct", 80 }, 81 "Weekday": { 82 Name: "Weekday", 83 Kind: "struct", 84 }, 85 }, 86 Types: map[TypeName]*Type{ 87 "Tweet": { 88 Kind: "struct", 89 Fields: map[Identifier]*Type{ 90 "Size": {Kind: "int"}, 91 "Message": {Kind: "string"}, 92 }, 93 }, 94 "Duration": { 95 Kind: "struct", 96 Fields: map[Identifier]*Type{ 97 "String": { 98 Kind: "func", 99 Arguments: []*Type{}, 100 Return: &Type{ 101 Kind: "string", 102 }, 103 }, 104 }, 105 }, 106 "time.Weekday": { 107 Kind: "struct", 108 Fields: map[Identifier]*Type{ 109 "String": { 110 Kind: "func", 111 Arguments: []*Type{}, 112 Return: &Type{ 113 Kind: "string", 114 }, 115 }, 116 }, 117 }, 118 "Weekday": { 119 Kind: "struct", 120 Fields: map[Identifier]*Type{ 121 "String": { 122 Kind: "func", 123 Arguments: []*Type{}, 124 Return: &Type{ 125 Kind: "string", 126 }, 127 }, 128 }, 129 }, 130 }, 131 PkgPath: "github.com/expr-lang/expr/docgen_test", 132 } 133 134 assert.EqualValues(t, expected, doc) 135 } 136 137 type A struct { 138 AmbiguousField int 139 OkField int 140 } 141 type B struct { 142 AmbiguousField string 143 } 144 145 type C struct { 146 A 147 B 148 } 149 type EnvAmbiguous struct { 150 A 151 B 152 C C 153 } 154 155 func TestCreateDoc_Ambiguous(t *testing.T) { 156 doc := CreateDoc(&EnvAmbiguous{}) 157 expected := &Context{ 158 Variables: map[Identifier]*Type{ 159 "A": { 160 Kind: "struct", 161 Name: "A", 162 }, 163 "B": { 164 Kind: "struct", 165 Name: "B", 166 }, 167 "OkField": { 168 Kind: "int", 169 }, 170 "C": { 171 Kind: "struct", 172 Name: "C", 173 }, 174 }, 175 Types: map[TypeName]*Type{ 176 "A": { 177 Kind: "struct", 178 Fields: map[Identifier]*Type{ 179 "AmbiguousField": {Kind: "int"}, 180 "OkField": {Kind: "int"}, 181 }, 182 }, 183 "B": { 184 Kind: "struct", 185 Fields: map[Identifier]*Type{ 186 "AmbiguousField": {Kind: "string"}, 187 }, 188 }, 189 "C": { 190 Kind: "struct", 191 Fields: map[Identifier]*Type{ 192 "A": {Kind: "struct", Name: "A"}, 193 "B": {Kind: "struct", Name: "B"}, 194 "OkField": {Kind: "int"}, 195 }, 196 }, 197 }, 198 PkgPath: "github.com/expr-lang/expr/docgen_test", 199 } 200 201 assert.EqualValues(t, expected, doc) 202 } 203 204 func TestCreateDoc_FromMap(t *testing.T) { 205 env := map[string]any{ 206 "Tweets": []*Tweet{}, 207 "Config": struct { 208 MaxSize int 209 }{}, 210 "Max": math.Max, 211 } 212 Operators = nil 213 Builtins = nil 214 doc := CreateDoc(env) 215 expected := &Context{ 216 Variables: map[Identifier]*Type{ 217 "Tweets": { 218 Kind: "array", 219 Type: &Type{ 220 Kind: "struct", 221 Name: "docgen_test.Tweet", 222 }, 223 }, 224 "Config": { 225 Kind: "struct", 226 Fields: map[Identifier]*Type{ 227 "MaxSize": {Kind: "int"}, 228 }, 229 }, 230 "Max": { 231 Kind: "func", 232 Arguments: []*Type{ 233 {Kind: "float"}, 234 {Kind: "float"}, 235 }, 236 Return: &Type{Kind: "float"}, 237 }, 238 }, 239 Types: map[TypeName]*Type{ 240 "docgen_test.Tweet": { 241 Kind: "struct", 242 Fields: map[Identifier]*Type{ 243 "Size": {Kind: "int"}, 244 "Message": {Kind: "string"}, 245 }, 246 }, 247 }, 248 } 249 250 require.EqualValues(t, expected, doc) 251 } 252 253 func TestContext_Markdown(t *testing.T) { 254 doc := CreateDoc(&Env{}) 255 md := doc.Markdown() 256 require.True(t, len(md) > 0) 257 }