All checks were successful
Test / Create distribution (push) Successful in 1m4s
Test / Sandbox (push) Successful in 2m46s
Test / Hakurei (push) Successful in 3m48s
Test / ShareFS (push) Successful in 3m45s
Test / Sandbox (race detector) (push) Successful in 5m19s
Test / Hakurei (race detector) (push) Successful in 6m28s
Test / Flake checks (push) Successful in 1m21s
Performance is sufficient for the use case, despite the fact that I could not even think of a lower-effort way to do this: BenchmarkParse-128 55100 21494 ns/op BenchmarkEvaluate-128 131670 9248 ns/op Signed-off-by: Ophestra <cat@gensokyo.uk>
170 lines
4.6 KiB
Go
170 lines
4.6 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, ExprError('}')},
|
|
{"bad sep", "f{v?}", nil, TokenError{'=', '?'}},
|
|
{"bad ident", "f{9}", nil, TokenError{scanner.Ident, scanner.Int}},
|
|
{"share bad sep", "f { v,,v = v; }", nil, ExprError(',')},
|
|
{"share missing sep", "f { v v }", nil, TokenError{',', scanner.Ident}},
|
|
|
|
{"ident", `v`, []any{Ident("v")}, nil},
|
|
{"concat", `f { v = v+"\xfd"+p{}+9; }`, []any{Func{
|
|
Ident: "f",
|
|
|
|
Args: []Arg{{K: []Ident{"v"}, V: Val{
|
|
Ident("v"),
|
|
String("\xfd"),
|
|
Func{Ident: "p"},
|
|
Int(9),
|
|
}}},
|
|
}}, nil},
|
|
{"truncated string concat", `f { v = v+; }`, nil,
|
|
ExprError(';')},
|
|
|
|
{"empty pairs", `{}`, []any{[]KV(nil)}, nil},
|
|
{"short kv", `{"\x00":v;}`, []any{[]KV{
|
|
{K: "\x00", V: Val{Ident("v")}},
|
|
}}, nil},
|
|
{"truncated kv", `{"\x00"`, nil, ExprError(scanner.EOF)},
|
|
{"ident kv", `{v="";}`, nil, ExprError(scanner.Ident)},
|
|
|
|
{"empty array", `[]`, []any{Array(nil)}, nil},
|
|
{"integer array", `[9]`, []any{Array{{Int(9)}}}, nil},
|
|
{"short array", `[ "\x00" ]`, []any{
|
|
Array{{String("\x00")}},
|
|
}, nil},
|
|
{"short array delim", `[ "\x00", ]`, []any{
|
|
Array{{String("\x00")}},
|
|
}, nil},
|
|
{"missing array value", `[ "\x00", , v ]`, nil, ExprError(',')},
|
|
{"missing array delimiter", `[ v0 v1 ]`, nil, TokenError{',', scanner.Ident}},
|
|
{"truncated array", `[ "\x00"`, nil,
|
|
ExprError(scanner.EOF)},
|
|
|
|
{"gcc", sample, []any{Func{
|
|
Ident: Ident("gcc"),
|
|
Package: true,
|
|
|
|
Args: []Arg{
|
|
{K: []Ident{Ident("description")}, V: Val{String("The GNU Compiler Collection")}},
|
|
{K: []Ident{Ident("website")}, V: Val{String("https://www.gnu.org/software/gcc")}},
|
|
{K: []Ident{Ident("anitya")}, V: Val{Int(6502)}},
|
|
|
|
{K: []Ident{Ident("version")}, V: Val{String("16.1.0")}, R: true},
|
|
{K: []Ident{Ident("source")}, V: Val{Func{
|
|
Ident: Ident("remoteTar"),
|
|
|
|
Args: []Arg{
|
|
{K: []Ident{Ident("url")}, V: Val{
|
|
String("https://ftp.tsukuba.wide.ad.jp/software/gcc/releases/"),
|
|
String("gcc-"),
|
|
Ident("version"),
|
|
String("/gcc-"),
|
|
Ident("version"),
|
|
String(".tar.gz"),
|
|
}},
|
|
{K: []Ident{Ident("checksum")}, V: Val{String("4ASoWbxaA2FW7PAB0zzHDPC5XnNhyaAyjtDPpGzceSLeYnEIXsNYZR3PA_Zu5P0K")}},
|
|
{K: []Ident{Ident("compress")}, V: Val{Ident("gzip")}},
|
|
},
|
|
}}},
|
|
{K: []Ident{Ident("patches")}, V: Val{Array{
|
|
{String("musl-off64_t-loff_t.patch")},
|
|
{String("musl-legacy-lfs.patch")},
|
|
}}},
|
|
|
|
{K: []Ident{Ident("exclusive")}, V: Val{Ident("true")}},
|
|
|
|
{K: []Ident{Ident("exec")}, V: Val{Func{
|
|
Ident: Ident("make"),
|
|
|
|
Args: []Arg{
|
|
{K: []Ident{Ident("configure")}, V: Val{[]KV{
|
|
{K: String("disable-multilib")},
|
|
{K: String("enable-default-pie")},
|
|
{K: String("disable-nls")},
|
|
{K: String("with-gnu-as")},
|
|
{K: String("with-gnu-ld")},
|
|
{K: String("with-system-zlib")},
|
|
{K: String("enable-languages"), V: Val{String("c,c++,go")}},
|
|
{K: String("with-native-system-header-dir"), V: Val{String("/system/include")}},
|
|
{K: String("with-multilib-list"), V: Val{Func{
|
|
Ident: Ident("arch"),
|
|
|
|
Args: []Arg{
|
|
{K: []Ident{Ident("amd64"), Ident("arm64")}, V: Val{String("''")}},
|
|
{K: []Ident{Ident("default")}, V: Val{Ident("unset")}},
|
|
},
|
|
}}},
|
|
}}},
|
|
{K: []Ident{Ident("make")}, V: Val{Array{
|
|
{String("BOOT_CFLAGS='-O2 -g'")},
|
|
{
|
|
Func{Ident: Ident("noop"), Args: []Arg{{K: []Ident{Ident("key")}, V: Val{Ident("value")}}}},
|
|
String("\x00"),
|
|
},
|
|
{String("bootstrap")},
|
|
}}},
|
|
|
|
{K: []Ident{Ident("skip-check")}, V: Val{Ident("true")}},
|
|
},
|
|
}}},
|
|
|
|
{K: []Ident{Ident("inputs")}, V: Val{Array{
|
|
{Ident("binutils")},
|
|
{Ident("mpc")},
|
|
{Ident("zlib")},
|
|
{Ident("libucontext")},
|
|
{Ident("kernel-headers")},
|
|
}}},
|
|
},
|
|
}}, nil},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p, err := 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)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkParse(b *testing.B) {
|
|
r := strings.NewReader(sample)
|
|
for b.Loop() {
|
|
if _, err := Parse(r); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
b.StopTimer()
|
|
r.Reset(sample)
|
|
b.StartTimer()
|
|
}
|
|
}
|