Files
hakurei/internal/rosa/azalea/azalea_test.go
Ophestra c2d44d5937 internal/rosa/azalea: ast and parser
This syntax is not final, but acts as a stopgap solution and a proof of concept.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-05-15 12:28:47 +09:00

150 lines
5.0 KiB
Go

package azalea_test
import (
_ "embed"
"reflect"
"strings"
"testing"
"text/scanner"
"hakurei.app/internal/rosa/azalea"
)
//go:embed testdata/gcc.az
var sample string
func TestParse(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
data string
want []any
err error
}{
{"invalid", "}", nil, azalea.ExprError('}')},
{"bad sep", "f{v?}", nil, azalea.TokenError{'=', '?'}},
{"bad ident", "f{9}", nil, azalea.TokenError{scanner.Ident, scanner.Int}},
{"share bad sep", "f { v,,v = v; }", nil, azalea.ExprError(',')},
{"share missing sep", "f { v v }", nil, azalea.TokenError{',', scanner.Ident}},
{"ident string", `v`, []any{azalea.StringSpec{
{Value: "v", Ident: true},
}}, nil},
{"ident string concat", `v+"\xfd"`, []any{azalea.StringSpec{
{Value: "v", Ident: true},
{Value: "\xfd"},
}}, nil},
{"truncated string concat", `v+`, nil,
azalea.TokenError{scanner.String, scanner.EOF}},
{"unexpected string concat", `v+9`, nil,
azalea.TokenError{scanner.String, scanner.Int}},
{"empty pairs", `{}`, []any{[]azalea.KV(nil)}, nil},
{"short kv", `{"\x00":v;}`, []any{[]azalea.KV{
{K: "\x00", V: azalea.StringSpec{azalea.String{Value: "v", Ident: true}}},
}}, nil},
{"truncated kv", `{"\x00"`, nil, azalea.ExprError(scanner.EOF)},
{"ident kv", `{v="";}`, nil, azalea.ExprError(scanner.Ident)},
{"empty array", `[]`, []any{[]any(nil)}, nil},
{"integer array", `[9]`, []any{[]any{int64(9)}}, nil},
{"short array", `[ "\x00" ]`, []any{
[]any{azalea.StringSpec{{Value: "\x00"}}},
}, nil},
{"short array delim", `[ "\x00", ]`, []any{
[]any{azalea.StringSpec{{Value: "\x00"}}},
}, nil},
{"missing array value", `[ "\x00", , v ]`, nil, azalea.ExprError(',')},
{"missing array delimiter", `[ v0 v1 ]`, nil, azalea.TokenError{',', scanner.Ident}},
{"truncated array", `[ "\x00"`, nil,
azalea.ExprError(scanner.EOF)},
{"gcc", sample, []any{azalea.Func{
Ident: "gcc",
Package: true,
Args: []azalea.Arg{
{K: []string{"description"}, V: azalea.StringSpec{{Value: "The GNU Compiler Collection"}}},
{K: []string{"website"}, V: azalea.StringSpec{{Value: "https://www.gnu.org/software/gcc"}}},
{K: []string{"anitya"}, V: int64(6502)},
{K: []string{"version"}, V: azalea.StringSpec{{Value: "16.1.0"}}, R: true},
{K: []string{"source"}, V: azalea.Func{Ident: "remoteTar", Package: false, Args: []azalea.Arg{
{K: []string{"url"}, V: azalea.StringSpec{
{Value: "https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"},
{Value: "gcc-"}, {Value: "version", Ident: true},
{Value: "/gcc-"}, {Value: "version", Ident: true},
{Value: ".tar.gz"},
}},
{K: []string{"checksum"}, V: azalea.StringSpec{
{Value: "4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K"},
}},
{K: []string{"compress"}, V: azalea.StringSpec{{Value: "gzip", Ident: true}}},
}}},
{K: []string{"patches"}, V: []any{
azalea.StringSpec{{Value: "musl-off64_t-loff_t.patch"}},
azalea.StringSpec{{Value: "musl-legacy-lfs.patch"}},
}},
{K: []string{"exclusive"}, V: azalea.StringSpec{{Value: "true", Ident: true}}},
{K: []string{"exec"}, V: azalea.Func{
Ident: "make",
Args: []azalea.Arg{
{K: []string{"configure"}, V: []azalea.KV{
{K: "disable-multilib"},
{K: "enable-default-pie"},
{K: "disable-nls"},
{K: "with-gnu-as"},
{K: "with-gnu-ld"},
{K: "with-system-zlib"},
{K: "enable-languages", V: azalea.StringSpec{{Value: "c,c++,go"}}},
{K: "with-native-system-header-dir", V: azalea.StringSpec{{Value: "/system/include"}}},
{K: "with-multilib-list", V: azalea.Func{
Ident: "arch",
Args: []azalea.Arg{
{K: []string{"amd64", "arm64"}, V: azalea.StringSpec{{Value: "''"}}},
{K: []string{"default"}, V: azalea.StringSpec{{Value: "unset", Ident: true}}},
},
}},
}},
{K: []string{"make"}, V: []any{
azalea.StringSpec{{Value: "BOOT_CFLAGS='-O2 -g'"}},
azalea.Func{
Ident: "noop",
Args: []azalea.Arg{
{K: []string{"key"}, V: azalea.StringSpec{
{Value: "value", Ident: true},
}},
},
},
azalea.StringSpec{{Value: "bootstrap"}},
}},
{K: []string{"skip-check"}, V: azalea.StringSpec{{Value: "true", Ident: true}}},
},
}},
{K: []string{"inputs"}, V: []any{
azalea.StringSpec{{Value: "binutils", Ident: true}},
azalea.StringSpec{{Value: "mpc", Ident: true}},
azalea.StringSpec{{Value: "zlib", Ident: true}},
azalea.StringSpec{{Value: "libucontext", Ident: true}},
azalea.StringSpec{{Value: "kernel-headers", Ident: true}},
}},
},
}}, nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
p, err := azalea.Parse(strings.NewReader(tc.data))
if !reflect.DeepEqual(p, tc.want) {
t.Errorf("Parse: %#v, want %#v", p, tc.want)
}
if !reflect.DeepEqual(err, tc.err) {
t.Errorf("Parse: error = %v, want %v", err, tc.err)
}
})
}
}