Hi… I am well aware that this diff view is very suboptimal. It will be fixed when the refactored server comes along!
scfg: Remove tests for now
module go.lindenii.runxiyu.org/forge go 1.24.1 require ( git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9 github.com/alecthomas/chroma/v2 v2.16.0 github.com/alexedwards/argon2id v1.0.0 github.com/bluekeyes/go-gitdiff v0.8.1
github.com/davecgh/go-spew v1.1.1
github.com/dustin/go-humanize v1.0.1 github.com/emersion/go-message v0.18.2 github.com/emersion/go-smtp v0.21.3 github.com/gliderlabs/ssh v0.3.8 github.com/go-git/go-git/v5 v5.14.0 github.com/jackc/pgx/v5 v5.7.4 github.com/microcosm-cc/bluemonday v1.0.27 github.com/niklasfasching/go-org v1.7.0 github.com/tdewolff/minify/v2 v2.22.4 github.com/yuin/goldmark v1.7.8 go.lindenii.runxiyu.org/lindenii-common v0.0.0-20250321131425-dda3538a9cd4 go.lindenii.runxiyu.org/lindenii-irc v0.0.0-20250322030600-1e47f911f1fa golang.org/x/crypto v0.36.0 ) require ( dario.cat/mergo v1.0.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/cloudflare/circl v1.6.0 // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.1 // indirect github.com/tdewolff/parse/v2 v2.7.21 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect )
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright (c) 2020 Simon Ser <https://emersion.fr>
package scfg
import (
"reflect"
"strings"
"testing"
"github.com/davecgh/go-spew/spew"
)
var readTests = []struct {
name string
src string
want Block
}{
{
name: "flat",
src: `dir1 param1 param2 "" param3
dir2
dir3 param1
# comment
dir4 "param 1" 'param 2'`,
want: Block{
{Name: "dir1", Params: []string{"param1", "param2", "", "param3"}},
{Name: "dir2", Params: []string{}},
{Name: "dir3", Params: []string{"param1"}},
{Name: "dir4", Params: []string{"param 1", "param 2"}},
},
},
{
name: "simpleBlocks",
src: `block1 {
dir1 param1 param2
dir2 param1
}
block2 {
}
block3 {
# comment
}
block4 param1 "param2" {
dir1
}`,
want: Block{
{
Name: "block1",
Params: []string{},
Children: Block{
{Name: "dir1", Params: []string{"param1", "param2"}},
{Name: "dir2", Params: []string{"param1"}},
},
},
{Name: "block2", Params: []string{}, Children: Block{}},
{Name: "block3", Params: []string{}, Children: Block{}},
{
Name: "block4",
Params: []string{"param1", "param2"},
Children: Block{
{Name: "dir1", Params: []string{}},
},
},
},
},
{
name: "nested",
src: `block1 {
block2 {
dir1 param1
}
block3 {
}
}
block4 {
block5 {
block6 param1 {
dir1
}
}
dir1
}`,
want: Block{
{
Name: "block1",
Params: []string{},
Children: Block{
{
Name: "block2",
Params: []string{},
Children: Block{
{Name: "dir1", Params: []string{"param1"}},
},
},
{
Name: "block3",
Params: []string{},
Children: Block{},
},
},
},
{
Name: "block4",
Params: []string{},
Children: Block{
{
Name: "block5",
Params: []string{},
Children: Block{{
Name: "block6",
Params: []string{"param1"},
Children: Block{{
Name: "dir1",
Params: []string{},
}},
}},
},
{
Name: "dir1",
Params: []string{},
},
},
},
},
},
{
name: "quotes",
src: `"a \b ' \" c" 'd \e \' " f' a\"b`,
want: Block{
{Name: "a b ' \" c", Params: []string{"d e ' \" f", "a\"b"}},
},
},
{
name: "quotes-2",
src: `dir arg1 "arg2" ` + `\"\"`,
want: Block{
{Name: "dir", Params: []string{"arg1", "arg2", "\"\""}},
},
},
{
name: "quotes-3",
src: `dir arg1 "\"\"\"\"" arg3`,
want: Block{
{Name: "dir", Params: []string{"arg1", `"` + "\"\"" + `"`, "arg3"}},
},
},
}
func TestRead(t *testing.T) {
for _, test := range readTests {
t.Run(test.name, func(t *testing.T) {
r := strings.NewReader(test.src)
got, err := Read(r)
if err != nil {
t.Fatalf("Read() = %v", err)
}
stripLineno(got)
if !reflect.DeepEqual(got, test.want) {
t.Error(spew.Sprintf("Read() = \n %v \n but want \n %v", got, test.want))
}
})
}
}
func stripLineno(block Block) {
for _, dir := range block {
dir.lineno = 0
stripLineno(dir.Children)
}
}
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright (c) 2020 Simon Ser <https://emersion.fr>
package scfg_test
import (
"fmt"
"log"
"reflect"
"strings"
"testing"
"go.lindenii.runxiyu.org/forge/internal/scfg"
)
func ExampleDecoder() {
var data struct {
Foo int `scfg:"foo"`
Bar struct {
Param string `scfg:",param"`
Baz string `scfg:"baz"`
} `scfg:"bar"`
}
raw := `foo 42
bar asdf {
baz hello
}
`
r := strings.NewReader(raw)
if err := scfg.NewDecoder(r).Decode(&data); err != nil {
log.Fatal(err)
}
fmt.Printf("Foo = %v\n", data.Foo)
fmt.Printf("Bar.Param = %v\n", data.Bar.Param)
fmt.Printf("Bar.Baz = %v\n", data.Bar.Baz)
// Output:
// Foo = 42
// Bar.Param = asdf
// Bar.Baz = hello
}
type nestedStructInner struct {
Bar string `scfg:"bar"`
}
type structParams struct {
Params []string `scfg:",param"`
Bar string
}
type textUnmarshaler struct {
text string
}
func (tu *textUnmarshaler) UnmarshalText(text []byte) error {
tu.text = string(text)
return nil
}
type textUnmarshalerParams struct {
Params []textUnmarshaler `scfg:",param"`
}
var barStr = "bar"
var unmarshalTests = []struct {
name string
raw string
want interface{}
}{
{
name: "stringMap",
raw: `hello world
foo bar`,
want: map[string]string{
"hello": "world",
"foo": "bar",
},
},
{
name: "simpleStruct",
raw: `MyString asdf
MyBool true
MyInt -42
MyUint 42
MyFloat 3.14`,
want: struct {
MyString string
MyBool bool
MyInt int
MyUint uint
MyFloat float32
}{
MyString: "asdf",
MyBool: true,
MyInt: -42,
MyUint: 42,
MyFloat: 3.14,
},
},
{
name: "simpleStructTag",
raw: `foo bar`,
want: struct {
Foo string `scfg:"foo"`
}{
Foo: "bar",
},
},
{
name: "sliceParams",
raw: `Foo a s d f`,
want: struct {
Foo []string
}{
Foo: []string{"a", "s", "d", "f"},
},
},
{
name: "arrayParams",
raw: `Foo a s d f`,
want: struct {
Foo [4]string
}{
Foo: [4]string{"a", "s", "d", "f"},
},
},
{
name: "pointers",
raw: `Foo bar`,
want: struct {
Foo *string
}{
Foo: &barStr,
},
},
{
name: "nestedMap",
raw: `foo {
bar baz
}`,
want: struct {
Foo map[string]string `scfg:"foo"`
}{
Foo: map[string]string{"bar": "baz"},
},
},
{
name: "nestedStruct",
raw: `foo {
bar baz
}`,
want: struct {
Foo nestedStructInner `scfg:"foo"`
}{
Foo: nestedStructInner{
Bar: "baz",
},
},
},
{
name: "structParams",
raw: `Foo param1 param2 {
Bar baz
}`,
want: struct {
Foo structParams
}{
Foo: structParams{
Params: []string{"param1", "param2"},
Bar: "baz",
},
},
},
{
name: "textUnmarshaler",
raw: `Foo param1
Bar param2
Baz param3`,
want: struct {
Foo []textUnmarshaler
Bar *textUnmarshaler
Baz textUnmarshalerParams
}{
Foo: []textUnmarshaler{{"param1"}},
Bar: &textUnmarshaler{"param2"},
Baz: textUnmarshalerParams{
Params: []textUnmarshaler{{"param3"}},
},
},
},
{
name: "directiveStructSlice",
raw: `Foo param1 param2 {
Bar baz
}
Foo param3 param4`,
want: struct {
Foo []structParams
}{
Foo: []structParams{
{
Params: []string{"param1", "param2"},
Bar: "baz",
},
{
Params: []string{"param3", "param4"},
},
},
},
},
{
name: "directiveMapSlice",
raw: `Foo {
key1 param1
}
Foo {
key2 param2
}`,
want: struct {
Foo []map[string]string
}{
Foo: []map[string]string{
{"key1": "param1"},
{"key2": "param2"},
},
},
},
}
func TestUnmarshal(t *testing.T) {
for _, tc := range unmarshalTests {
tc := tc // capture variable
t.Run(tc.name, func(t *testing.T) {
testUnmarshal(t, tc.raw, tc.want)
})
}
}
func testUnmarshal(t *testing.T, raw string, want interface{}) {
out := reflect.New(reflect.TypeOf(want))
r := strings.NewReader(raw)
if err := scfg.NewDecoder(r).Decode(out.Interface()); err != nil {
t.Fatalf("Decode() = %v", err)
}
got := out.Elem().Interface()
if !reflect.DeepEqual(got, want) {
t.Errorf("Decode() = \n%#v\n but want \n%#v", got, want)
}
}
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright (c) 2020 Simon Ser <https://emersion.fr>
package scfg
import (
"bytes"
"testing"
)
func TestWrite(t *testing.T) {
for _, tc := range []struct {
src Block
want string
err error
}{
{
src: Block{},
want: "",
},
{
src: Block{{
Name: "dir",
Children: Block{{
Name: "blk1",
Params: []string{"p1", `"p2"`},
Children: Block{
{
Name: "sub1",
Params: []string{"arg11", "arg12"},
},
{
Name: "sub2",
Params: []string{"arg21", "arg22"},
},
{
Name: "sub3",
Params: []string{"arg31", "arg32"},
Children: Block{
{
Name: "sub-sub1",
},
{
Name: "sub-sub2",
Params: []string{"arg321", "arg322"},
},
},
},
},
}},
}},
want: `dir {
blk1 p1 "\"p2\"" {
sub1 arg11 arg12
sub2 arg21 arg22
sub3 arg31 arg32 {
sub-sub1
sub-sub2 arg321 arg322
}
}
}
`,
},
{
src: Block{{Name: "dir1"}},
want: "dir1\n",
},
{
src: Block{{Name: "dir\"1"}},
want: "\"dir\\\"1\"\n",
},
{
src: Block{{Name: "dir'1"}},
want: "\"dir'1\"\n",
},
{
src: Block{{Name: "dir:}"}},
want: "\"dir:}\"\n",
},
{
src: Block{{Name: "dir:{"}},
want: "\"dir:{\"\n",
},
{
src: Block{{Name: "dir\t1"}},
want: `"dir` + "\t" + `1"` + "\n",
},
{
src: Block{{Name: "dir 1"}},
want: "\"dir 1\"\n",
},
{
src: Block{{Name: "dir1", Params: []string{"arg1", "arg2", `"arg3"`}}},
want: "dir1 arg1 arg2 " + `"\"arg3\""` + "\n",
},
{
src: Block{{Name: "dir1", Params: []string{"arg1", "arg 2", "arg'3"}}},
want: "dir1 arg1 \"arg 2\" \"arg'3\"\n",
},
{
src: Block{{Name: "dir1", Params: []string{"arg1", "", "arg3"}}},
want: "dir1 arg1 \"\" arg3\n",
},
{
src: Block{{Name: "dir1", Params: []string{"arg1", `"` + "\"\"" + `"`, "arg3"}}},
want: "dir1 arg1 " + `"\"\"\"\""` + " arg3\n",
},
{
src: Block{{
Name: "dir1",
Children: Block{
{Name: "sub1"},
{Name: "sub2", Params: []string{"arg1", "arg2"}},
},
}},
want: `dir1 {
sub1
sub2 arg1 arg2
}
`,
},
{
src: Block{{Name: ""}},
err: errDirEmptyName,
},
{
src: Block{{
Name: "dir",
Children: Block{
{Name: "sub1"},
{Name: "", Children: Block{{Name: "sub21"}}},
},
}},
err: errDirEmptyName,
},
} {
t.Run("", func(t *testing.T) {
var buf bytes.Buffer
err := Write(&buf, tc.src)
switch {
case err != nil && tc.err != nil:
if got, want := err.Error(), tc.err.Error(); got != want {
t.Fatalf("invalid error:\ngot= %q\nwant=%q", got, want)
}
return
case err == nil && tc.err != nil:
t.Fatalf("got err=nil, want=%q", tc.err.Error())
case err != nil && tc.err == nil:
t.Fatalf("could not marshal: %+v", err)
case err == nil && tc.err == nil:
// ok.
}
if got, want := buf.String(), tc.want; got != want {
t.Fatalf(
"invalid marshal representation:\ngot:\n%s\nwant:\n%s\n---",
got, want,
)
}
})
}
}