Lindenii Project Forge
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, ) } }) } }