diff --git a/frame/g/g_z_unit_test.go b/frame/g/g_z_unit_test.go index 8f2ed484d..d0f71778b 100644 --- a/frame/g/g_z_unit_test.go +++ b/frame/g/g_z_unit_test.go @@ -2,11 +2,12 @@ package g_test import ( "context" + "os" + "testing" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/test/gtest" "github.com/gogf/gf/v2/util/gutil" - "os" - "testing" ) var ( @@ -60,6 +61,13 @@ func Test_TryCatch(t *testing.T) { g.Dump(exception) }) }) + gtest.C(t, func(t *gtest.T) { + g.TryCatch(ctx, func(ctx context.Context) { + g.Throw("GoFrame") + }, func(ctx context.Context, exception error) { + t.Assert(exception.Error(), "GoFrame") + }) + }) } func Test_IsNil(t *testing.T) { diff --git a/frame/gins/gins_z_unit_server_test.go b/frame/gins/gins_z_unit_server_test.go index 132f6c562..6aa835c88 100644 --- a/frame/gins/gins_z_unit_server_test.go +++ b/frame/gins/gins_z_unit_server_test.go @@ -4,32 +4,48 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package gins +package gins_test -//func Test_Server(t *testing.T) { -// gtest.C(t, func(t *gtest.T) { -// var ( -// path = gcfg.DefaultConfigFileName -// serverConfigContent = gtest.DataContent("server", "config.yaml") -// err = gfile.PutContents(path, serverConfigContent) -// ) -// t.AssertNil(err) -// defer gfile.Remove(path) -// -// time.Sleep(time.Second) -// -// instance.Clear() -// defer instance.Clear() -// -// s := Server("tempByInstanceName") -// s.BindHandler("/", func(r *ghttp.Request) { -// r.Response.Write("hello") -// }) -// s.SetDumpRouterMap(false) -// t.AssertNil(s.Start()) -// defer t.AssertNil(s.Shutdown()) -// -// content := HttpClient().GetContent(gctx.New(), `http://127.0.0.1:8003/`) -// t.Assert(content, `hello`) -// }) -//} +import ( + "fmt" + "testing" + "time" + + "github.com/gogf/gf/v2/frame/gins" + "github.com/gogf/gf/v2/internal/instance" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gcfg" + "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/test/gtest" +) + +func Test_Server(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + var ( + path = gcfg.DefaultConfigFileName + serverConfigContent = gtest.DataContent("server", "config.yaml") + err = gfile.PutContents(path, serverConfigContent) + ) + t.AssertNil(err) + defer gfile.Remove(path) + + instance.Clear() + defer instance.Clear() + + s := gins.Server("tempByInstanceName") + s.BindHandler("/", func(r *ghttp.Request) { + r.Response.Write("hello") + }) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + + prefix := fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()) + client := gins.HttpClient() + client.SetPrefix(prefix) + t.Assert(client.GetContent(gctx.New(), "/"), "hello") + }) +} diff --git a/frame/gins/testdata/server/config.yaml b/frame/gins/testdata/server/config.yaml index 3be493af7..b269b7007 100644 --- a/frame/gins/testdata/server/config.yaml +++ b/frame/gins/testdata/server/config.yaml @@ -1,4 +1,4 @@ server: address: ":8000" tempByInstanceName: - address: ":8003" \ No newline at end of file + accessLogEnabled: false \ No newline at end of file diff --git a/i18n/gi18n/gi18n_z_unit_test.go b/i18n/gi18n/gi18n_z_unit_test.go index c05085895..d34b16345 100644 --- a/i18n/gi18n/gi18n_z_unit_test.go +++ b/i18n/gi18n/gi18n_z_unit_test.go @@ -7,6 +7,7 @@ package gi18n_test import ( + "github.com/gogf/gf/v2/os/gctx" _ "github.com/gogf/gf/v2/os/gres/testdata/data" "context" @@ -155,3 +156,26 @@ func Test_Resource(t *testing.T) { t.Assert(m.T(context.Background(), "{#hello}{#world}"), "你好世界") }) } + +func Test_SetCtxLanguage(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + ctx := gctx.New() + t.Assert(gi18n.LanguageFromCtx(ctx), "") + }) + + gtest.C(t, func(t *gtest.T) { + t.Assert(gi18n.LanguageFromCtx(nil), "") + }) + + gtest.C(t, func(t *gtest.T) { + ctx := gctx.New() + ctx = gi18n.WithLanguage(ctx, "zh-CN") + t.Assert(gi18n.LanguageFromCtx(ctx), "zh-CN") + }) + + gtest.C(t, func(t *gtest.T) { + ctx := gi18n.WithLanguage(nil, "zh-CN") + t.Assert(gi18n.LanguageFromCtx(ctx), "zh-CN") + }) + +} diff --git a/os/gcfg/gcfg_z_unit_adapter_file_test.go b/os/gcfg/gcfg_z_unit_adapter_file_test.go index c1e896b0f..d44c1f2fc 100644 --- a/os/gcfg/gcfg_z_unit_adapter_file_test.go +++ b/os/gcfg/gcfg_z_unit_adapter_file_test.go @@ -16,6 +16,35 @@ import ( "github.com/gogf/gf/v2/test/gtest" ) +func TestAdapterFile_Dump(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + c, err := gcfg.NewAdapterFile("config.yml") + t.AssertNil(err) + + t.Assert(c.GetFileName(), "config.yml") + + c.Dump() + c.Data(ctx) + }) + + gtest.C(t, func(t *gtest.T) { + c, err := gcfg.NewAdapterFile("testdata/default/config.toml") + t.AssertNil(err) + + c.Dump() + c.Data(ctx) + c.GetPaths() + }) + +} +func TestAdapterFile_Available(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + c, err := gcfg.NewAdapterFile("testdata/default/config.toml") + t.AssertNil(err) + c.Available(ctx) + }) +} + func TestAdapterFile_SetPath(t *testing.T) { gtest.C(t, func(t *gtest.T) { c, err := gcfg.NewAdapterFile("config.yml") @@ -24,6 +53,15 @@ func TestAdapterFile_SetPath(t *testing.T) { err = c.SetPath("/tmp") t.AssertNil(err) + err = c.SetPath("notexist") + t.AssertNE(err, nil) + + err = c.SetPath("testdata/c1.toml") + t.AssertNE(err, nil) + + err = c.SetPath("") + t.AssertNil(err) + err = c.SetPath("gcfg.go") t.AssertNE(err, nil) @@ -41,6 +79,15 @@ func TestAdapterFile_AddPath(t *testing.T) { err = c.AddPath("/tmp") t.AssertNil(err) + err = c.AddPath("notexist") + t.AssertNE(err, nil) + + err = c.SetPath("testdata/c1.toml") + t.AssertNE(err, nil) + + err = c.SetPath("") + t.AssertNil(err) + err = c.AddPath("gcfg.go") t.AssertNE(err, nil) diff --git a/os/gview/gview_config.go b/os/gview/gview_config.go index 445829200..447f75f9e 100644 --- a/os/gview/gview_config.go +++ b/os/gview/gview_config.go @@ -86,7 +86,12 @@ func (view *View) SetConfigWithMap(m map[string]interface{}) error { _, v1 := gutil.MapPossibleItemByKey(m, "paths") _, v2 := gutil.MapPossibleItemByKey(m, "path") if v1 == nil && v2 != nil { - m["paths"] = []interface{}{v2} + switch v2.(type) { + case string: + m["paths"] = []string{v2.(string)} + case []string: + m["paths"] = v2 + } } err := gconv.Struct(m, &view.config) if err != nil { diff --git a/os/gview/gview_z_unit_config_test.go b/os/gview/gview_z_unit_config_test.go index f138203c0..98369c6cd 100644 --- a/os/gview/gview_z_unit_config_test.go +++ b/os/gview/gview_z_unit_config_test.go @@ -11,11 +11,15 @@ import ( "testing" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/i18n/gi18n" + "github.com/gogf/gf/v2/internal/command" "github.com/gogf/gf/v2/os/gview" "github.com/gogf/gf/v2/test/gtest" ) func Test_Config(t *testing.T) { + // show error print + command.Init("-gf.gview.errorprint=true") gtest.C(t, func(t *gtest.T) { config := gview.Config{ Paths: []string{gtest.DataPath("config")}, @@ -25,10 +29,13 @@ func Test_Config(t *testing.T) { DefaultFile: "test.html", Delimiters: []string{"${", "}"}, } + view := gview.New() err := view.SetConfig(config) t.AssertNil(err) + view.SetI18n(gi18n.New()) + str := `hello ${.name},version:${.version}` view.Assigns(g.Map{"version": "1.7.0"}) result, err := view.ParseContent(context.TODO(), str, nil) @@ -38,6 +45,38 @@ func Test_Config(t *testing.T) { result, err = view.ParseDefault(context.TODO()) t.AssertNil(err) t.Assert(result, "name:gf") + + t.Assert(view.GetDefaultFile(), "test.html") + }) + // SetConfig path fail: notexist + gtest.C(t, func(t *gtest.T) { + config := gview.Config{ + Paths: []string{"notexist", gtest.DataPath("config/test.html")}, + Data: g.Map{ + "name": "gf", + }, + DefaultFile: "test.html", + Delimiters: []string{"${", "}"}, + } + + view := gview.New() + err := view.SetConfig(config) + t.AssertNE(err, nil) + }) + // SetConfig path fail: set file path + gtest.C(t, func(t *gtest.T) { + config := gview.Config{ + Paths: []string{gtest.DataPath("config/test.html")}, + Data: g.Map{ + "name": "gf", + }, + DefaultFile: "test.html", + Delimiters: []string{"${", "}"}, + } + + view := gview.New() + err := view.SetConfig(config) + t.AssertNE(err, nil) }) } @@ -64,4 +103,56 @@ func Test_ConfigWithMap(t *testing.T) { t.AssertNil(err) t.Assert(result, "name:gf") }) + // path as paths + gtest.C(t, func(t *gtest.T) { + view := gview.New() + err := view.SetConfigWithMap(g.Map{ + "Path": gtest.DataPath("config"), + "DefaultFile": "test.html", + "Delimiters": []string{"${", "}"}, + "Data": g.Map{ + "name": "gf", + }, + }) + t.AssertNil(err) + + str := `hello ${.name},version:${.version}` + view.Assigns(g.Map{"version": "1.7.0"}) + result, err := view.ParseContent(context.TODO(), str, nil) + t.AssertNil(err) + t.Assert(result, "hello gf,version:1.7.0") + + result, err = view.ParseDefault(context.TODO()) + t.AssertNil(err) + t.Assert(result, "name:gf") + }) + // path as paths + gtest.C(t, func(t *gtest.T) { + view := gview.New() + err := view.SetConfigWithMap(g.Map{ + "Path": []string{gtest.DataPath("config")}, + "DefaultFile": "test.html", + "Delimiters": []string{"${", "}"}, + "Data": g.Map{ + "name": "gf", + }, + }) + t.AssertNil(err) + + str := `hello ${.name},version:${.version}` + view.Assigns(g.Map{"version": "1.7.0"}) + result, err := view.ParseContent(context.TODO(), str, nil) + t.AssertNil(err) + t.Assert(result, "hello gf,version:1.7.0") + + result, err = view.ParseDefault(context.TODO()) + t.AssertNil(err) + t.Assert(result, "name:gf") + }) + // map is nil + gtest.C(t, func(t *gtest.T) { + view := gview.New() + err := view.SetConfigWithMap(nil) + t.AssertNE(err, nil) + }) } diff --git a/os/gview/gview_z_unit_i18n_test.go b/os/gview/gview_z_unit_i18n_test.go index dfd1e4026..bf2e7d219 100644 --- a/os/gview/gview_z_unit_i18n_test.go +++ b/os/gview/gview_z_unit_i18n_test.go @@ -12,7 +12,10 @@ import ( "github.com/gogf/gf/v2/debug/gdebug" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/i18n/gi18n" + "github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gview" "github.com/gogf/gf/v2/test/gtest" ) @@ -75,4 +78,38 @@ func Test_I18n(t *testing.T) { t.AssertNil(err) t.Assert(result3, expect3) }) + // gi18n manager is nil + gtest.C(t, func(t *gtest.T) { + content := `{{.name}} says "{#hello}{#world}!"` + expect1 := `john says "{#hello}{#world}!"` + + g.I18n().SetPath(gdebug.CallerDirectory() + gfile.Separator + "testdata" + gfile.Separator + "i18n") + + view := gview.New() + view.SetI18n(nil) + result1, err := view.ParseContent(context.TODO(), content, g.Map{ + "name": "john", + "I18nLanguage": "zh-CN", + }) + t.AssertNil(err) + t.Assert(result1, expect1) + }) + // SetLanguage in context + gtest.C(t, func(t *gtest.T) { + content := `{{.name}} says "{#hello}{#world}!"` + expect1 := `john says "你好世界!"` + ctx := gctx.New() + g.I18n().SetPath(gdebug.CallerDirectory() + gfile.Separator + "testdata" + gfile.Separator + "i18n") + ctx = gi18n.WithLanguage(ctx, "zh-CN") + t.Log(gi18n.LanguageFromCtx(ctx)) + + view := gview.New() + + result1, err := view.ParseContent(ctx, content, g.Map{ + "name": "john", + }) + t.AssertNil(err) + t.Assert(result1, expect1) + }) + } diff --git a/os/gview/gview_z_unit_test.go b/os/gview/gview_z_unit_test.go index 8fe06d8d8..f345835ea 100644 --- a/os/gview/gview_z_unit_test.go +++ b/os/gview/gview_z_unit_test.go @@ -18,11 +18,13 @@ import ( "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gres" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/os/gview" "github.com/gogf/gf/v2/test/gtest" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" + "github.com/gogf/gf/v2/util/gmode" "github.com/gogf/gf/v2/util/guid" ) @@ -222,7 +224,9 @@ func Test_FuncInclude(t *testing.T) { footer = `

FOOTER

` layout = `{{include "header.html" .}} {{include "main.html" .}} -{{include "footer.html" .}}` +{{include "footer.html" .}} +{{include "footer_not_exist.html" .}} +{{include "" .}}` templatePath = gfile.Temp(guid.S()) ) @@ -243,7 +247,9 @@ func Test_FuncInclude(t *testing.T) { t.AssertNil(err) t.Assert(result, `

HEADER

hello gf

-

FOOTER

`) +

FOOTER

+template file "footer_not_exist.html" not found +`) t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `notfound.html`), "notfound")) result, err = view.Parse(context.TODO(), "notfound.html") @@ -379,6 +385,14 @@ func Test_BuildInFuncMap(t *testing.T) { t.Assert(gstr.Contains(r, "Name:john"), true) t.Assert(gstr.Contains(r, "Score:99.9"), true) }) + + gtest.C(t, func(t *gtest.T) { + v := gview.New() + r, err := v.ParseContent(context.TODO(), "{{range $k, $v := map }} {{$k}}:{{$v}} {{end}}") + t.AssertNil(err) + t.Assert(gstr.Contains(r, "Name:john"), false) + t.Assert(gstr.Contains(r, "Score:99.9"), false) + }) } type TypeForBuildInFuncMaps struct { @@ -401,6 +415,14 @@ func Test_BuildInFuncMaps(t *testing.T) { t.AssertNil(err) t.Assert(r, ` 0:john 99.9 1:smith 100 `) }) + + gtest.C(t, func(t *gtest.T) { + v := gview.New() + v.Assign("v", new(TypeForBuildInFuncMaps)) + r, err := v.ParseContent(context.TODO(), "{{range $k, $v := maps }} {{$k}}:{{$v.Name}} {{$v.Score}} {{end}}") + t.AssertNil(err) + t.Assert(r, ``) + }) } func Test_BuildInFuncDump(t *testing.T) { @@ -416,6 +438,22 @@ func Test_BuildInFuncDump(t *testing.T) { t.Assert(gstr.Contains(r, `"name": "john"`), true) t.Assert(gstr.Contains(r, `"score": 100`), true) }) + + gtest.C(t, func(t *gtest.T) { + mode := gmode.Mode() + gmode.SetTesting() + defer gmode.Set(mode) + v := gview.New() + v.Assign("v", g.Map{ + "name": "john", + "score": 100, + }) + r, err := v.ParseContent(context.TODO(), "{{dump .}}") + t.AssertNil(err) + fmt.Println(r) + t.Assert(gstr.Contains(r, `"name": "john"`), false) + t.Assert(gstr.Contains(r, `"score": 100`), false) + }) } func Test_BuildInFuncJson(t *testing.T) { @@ -552,6 +590,12 @@ func Test_BuildInFuncDivide(t *testing.T) { t.AssertNil(err) t.Assert(r, `2`) }) + gtest.C(t, func(t *gtest.T) { + v := gview.New() + r, err := v.ParseContent(gctx.New(), "{{divide 8 0}}") + t.AssertNil(err) + t.Assert(r, `0`) + }) } func Test_Issue1416(t *testing.T) { @@ -570,3 +614,24 @@ func Test_Issue1416(t *testing.T) { t.Assert(r, `test.tpl content, vars: world`) }) } + +// template/gview_test.html +// name:{{.name}} +func init() { + if err := gres.Add("H4sIAAAAAAAC/wrwZmYRYeBg4GBIFA0LY0ACEgycDCWpuQU5iSWp+ullmanl8SWpxSV6GSW5OaEhrAyM5o1fk095n/HdumrdNeaLW7c2MDAw/P8f4M3OoZ+9QESIgYGBj4GBAWYBA0MTmgUcSBaADSxt/JoM0o6sKMCbkUmEGeFCZKNBLoSBbY0gkqB7EcZhdw8ECDD8d0xEMg7JdaxsIAVMDEwMfQwMDAvAygEBAAD//0d6jptEAQAA"); err != nil { + panic("add binary content to resource manager failed: " + err.Error()) + } +} + +func Test_GviewInGres(t *testing.T) { + gres.Dump() + gtest.C(t, func(t *gtest.T) { + v := gview.New() + v.SetPath("template") + result, err := v.Parse(context.TODO(), "gview_test.html", g.Map{ + "name": "john", + }) + t.AssertNil(err) + t.Assert(result, "name:john") + }) +} diff --git a/test/gtest/gtest_util.go b/test/gtest/gtest_util.go index ec1c99bc0..7afd869fb 100644 --- a/test/gtest/gtest_util.go +++ b/test/gtest/gtest_util.go @@ -221,6 +221,7 @@ func AssertLE(value, expect interface{}) { // The `expect` should be a slice, // but the `value` can be a slice or a basic type variable. // TODO map support. +// TODO: gconv.Strings(0) is not [0] func AssertIN(value, expect interface{}) { var ( passed = true diff --git a/test/gtest/gtest_z_unit_test.go b/test/gtest/gtest_z_unit_test.go index ac6f698e8..534820d10 100644 --- a/test/gtest/gtest_z_unit_test.go +++ b/test/gtest/gtest_z_unit_test.go @@ -7,18 +7,38 @@ package gtest_test import ( + "errors" + "path/filepath" "strconv" "testing" "github.com/gogf/gf/v2/test/gtest" ) +var ( + map1 = map[string]string{"k1": "v1"} + map1Expect = map[string]string{"k1": "v1"} + map2 = map[string]string{"k2": "v2"} + mapLong1 = map[string]string{"k1": "v1", "k2": "v2"} + mapLong1Expect = map[string]string{"k2": "v2", "k1": "v1"} +) + func TestC(t *testing.T) { gtest.C(t, func(t *gtest.T) { t.Assert(1, 1) t.AssertNE(1, 0) t.AssertEQ(float32(123.456), float32(123.456)) t.AssertEQ(float32(123.456), float32(123.456)) + t.Assert(map[string]string{"1": "1"}, map[string]string{"1": "1"}) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 == 0") + } + }() + t.Assert(1, 0) }) } @@ -32,19 +52,48 @@ func TestCase(t *testing.T) { } func TestAssert(t *testing.T) { + gtest.C(t, func(t *gtest.T) { var ( nilChan chan struct{} ) t.Assert(1, 1) t.Assert(nilChan, nil) - m1 := map[string]string{"k1": "v1", "k2": "v2"} - m2 := map[string]string{"k2": "v2", "k1": "v1"} - t.Assert(m1, m2) + t.Assert(map1, map1Expect) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT VALUE map["k2"]: == map["k2"]:v2 +GIVEN : map[k1:v1] +EXPECT: map[k2:v2]`) + } + }() + t.Assert(map1, map2) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT MAP LENGTH 2 == 1`) + } + }() + t.Assert(mapLong1, map2) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT VALUE TO BE A MAP, BUT GIVEN "int"`) + } + }() + t.Assert(0, map1) }) } func TestAssertEQ(t *testing.T) { + gtest.C(t, func(t *gtest.T) { var ( nilChan chan struct{} @@ -52,9 +101,54 @@ func TestAssertEQ(t *testing.T) { t.AssertEQ(nilChan, nil) t.AssertEQ("0", "0") t.AssertEQ(float32(123.456), float32(123.456)) - m1 := map[string]string{"k1": "v1", "k2": "v2"} - m2 := map[string]string{"k2": "v2", "k1": "v1"} - t.AssertEQ(m1, m2) + t.AssertEQ(mapLong1, mapLong1Expect) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 == 0") + } + }() + t.AssertEQ(1, 0) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT TYPE 1[int] == 1[string]") + } + }() + t.AssertEQ(1, "1") + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT VALUE map["k2"]: == map["k2"]:v2 +GIVEN : map[k1:v1] +EXPECT: map[k2:v2]`) + } + }() + t.AssertEQ(map1, map2) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT MAP LENGTH 2 == 1`) + } + }() + t.AssertEQ(mapLong1, map2) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT VALUE TO BE A MAP, BUT GIVEN "int"`) + } + }() + t.AssertEQ(0, map1) }) } @@ -66,9 +160,25 @@ func TestAssertNE(t *testing.T) { t.AssertNE(nil, c) t.AssertNE("0", "1") t.AssertNE(float32(123.456), float32(123.4567)) - m1 := map[string]string{"k1": "v1", "k2": "v2"} - m2 := map[string]string{"k2": "v1", "k1": "v2"} - t.AssertNE(m1, m2) + t.AssertNE(map1, map2) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 != 1") + } + }() + t.AssertNE(1, 1) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, `[ASSERT] EXPECT map[k1:v1] != map[k1:v1]`) + } + }() + t.AssertNE(map1, map1Expect) }) } @@ -77,6 +187,24 @@ func TestAssertNQ(t *testing.T) { t.AssertNQ(1, "0") t.AssertNQ(float32(123.456), float64(123.4567)) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 != 1") + } + }() + t.AssertNQ(1, "1") + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT TYPE 1[int] != 1[int]") + } + }() + t.AssertNQ(1, 1) + }) } func TestAssertGT(t *testing.T) { @@ -86,6 +214,15 @@ func TestAssertGT(t *testing.T) { t.AssertGT(uint(1), uint(0)) t.AssertGT(float32(123.45678), float32(123.4567)) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT -1 > 1") + } + }() + t.AssertGT(-1, 1) + }) } func TestAssertGE(t *testing.T) { @@ -99,6 +236,15 @@ func TestAssertGE(t *testing.T) { t.AssertGE(float32(123.45678), float32(123.4567)) t.AssertGE(float32(123.456), float32(123.456)) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT -1(int) >= 1(int)") + } + }() + t.AssertGE(-1, 1) + }) } func TestAssertLT(t *testing.T) { @@ -108,6 +254,15 @@ func TestAssertLT(t *testing.T) { t.AssertLT(uint(0), uint(1)) t.AssertLT(float32(123.456), float32(123.4567)) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 < -1") + } + }() + t.AssertLT(1, -1) + }) } func TestAssertLE(t *testing.T) { @@ -121,6 +276,15 @@ func TestAssertLE(t *testing.T) { t.AssertLE(float32(123.456), float32(123.4567)) t.AssertLE(float32(123.456), float32(123.456)) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 <= -1") + } + }() + t.AssertLE(1, -1) + }) } func TestAssertIN(t *testing.T) { @@ -128,6 +292,26 @@ func TestAssertIN(t *testing.T) { t.AssertIN("a", []string{"a", "b", "c"}) t.AssertIN(1, []int{1, 2, 3}) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] INVALID EXPECT VALUE TYPE: int") + } + }() + t.AssertIN(0, 0) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 4 IN [1 2 3]") + } + }() + // t.AssertIN(0, []int{0, 1, 2, 3}) + // t.AssertIN(0, []int{ 1, 2, 3}) + t.AssertIN(4, []int{1, 2, 3}) + }) } func TestAssertNI(t *testing.T) { @@ -135,6 +319,24 @@ func TestAssertNI(t *testing.T) { t.AssertNI("d", []string{"a", "b", "c"}) t.AssertNI(4, []int{1, 2, 3}) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] INVALID EXPECT VALUE TYPE: int") + } + }() + t.AssertNI(0, 0) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ASSERT] EXPECT 1 NOT IN [1 2 3]") + } + }() + t.AssertNI(1, []int{1, 2, 3}) + }) } func TestAssertNil(t *testing.T) { @@ -146,4 +348,46 @@ func TestAssertNil(t *testing.T) { _, err := strconv.ParseInt("123", 10, 64) t.AssertNil(err) }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "error") + } + }() + t.AssertNil(errors.New("error")) + }) + + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.AssertNE(err, nil) + } + }() + t.AssertNil(1) + }) +} + +func TestAssertError(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + defer func() { + if err := recover(); err != nil { + t.Assert(err, "[ERROR] this is an error") + } + }() + t.Error("this is an error") + }) +} + +func TestDataPath(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + t.Assert(filepath.ToSlash(gtest.DataPath("testdata.txt")), `./testdata/testdata.txt`) + }) +} + +func TestDataContent(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + t.Assert(gtest.DataContent("testdata.txt"), `hello`) + t.Assert(gtest.DataContent(""), "") + }) } diff --git a/test/gtest/testdata/testdata.txt b/test/gtest/testdata/testdata.txt new file mode 100644 index 000000000..b6fc4c620 --- /dev/null +++ b/test/gtest/testdata/testdata.txt @@ -0,0 +1 @@ +hello \ No newline at end of file diff --git a/text/gstr/gstr_version.go b/text/gstr/gstr_version.go index d7064513e..f931b2c9d 100644 --- a/text/gstr/gstr_version.go +++ b/text/gstr/gstr_version.go @@ -39,9 +39,13 @@ func IsGNUVersion(version string) bool { } // CompareVersion compares `a` and `b` as standard GNU version. +// // It returns 1 if `a` > `b`. +// // It returns -1 if `a` < `b`. +// // It returns 0 if `a` = `b`. +// // GNU standard version is like: // v1.0 // 1 @@ -86,17 +90,24 @@ func CompareVersion(a, b string) int { } // CompareVersionGo compares `a` and `b` as standard Golang version. +// // It returns 1 if `a` > `b`. +// // It returns -1 if `a` < `b`. +// // It returns 0 if `a` = `b`. +// // Golang standard version is like: // 1.0.0 // v1.0.1 // v2.10.8 // 10.2.0 // v0.0.0-20190626092158-b2ccc519800e +// v1.12.2-0.20200413154443-b17e3a6804fa // v4.20.0+incompatible // etc. +// +// Docs: https://go.dev/doc/modules/version-numbers func CompareVersionGo(a, b string) int { a = Trim(a) b = Trim(b) @@ -131,30 +142,31 @@ func CompareVersionGo(a, b string) int { var ( array1 = strings.Split(a, ".") array2 = strings.Split(b, ".") - diff int + diff = len(array1) - len(array2) ) - // Specially in Golang: - // "v1.12.2-0.20200413154443-b17e3a6804fa" < "v1.12.2" - if len(array1) > 3 && len(array2) <= 3 { - return -1 - } - if len(array1) <= 3 && len(array2) > 3 { - return 1 - } - diff = len(array2) - len(array1) - for i := 0; i < diff; i++ { + for i := diff; i < 0; i++ { array1 = append(array1, "0") } - diff = len(array1) - len(array2) for i := 0; i < diff; i++ { array2 = append(array2, "0") } - v1 := 0 - v2 := 0 + + // check Major.Minor.Patch first + v1, v2 := 0, 0 for i := 0; i < len(array1); i++ { - v1 = gconv.Int(array1[i]) - v2 = gconv.Int(array2[i]) + v1, v2 = gconv.Int(array1[i]), gconv.Int(array2[i]) + // Specially in Golang: + // "v1.12.2-0.20200413154443-b17e3a6804fa" < "v1.12.2" + // "v1.12.3-0.20200413154443-b17e3a6804fa" > "v1.12.2" + if i == 4 && v1 != v2 && (v1 == 0 || v2 == 0) { + if v1 > v2 { + return -1 + } else { + return 1 + } + } + if v1 > v2 { return 1 } @@ -162,13 +174,16 @@ func CompareVersionGo(a, b string) int { return -1 } } + // Specially in Golang: // "v4.20.1+incompatible" < "v4.20.1" - if Contains(rawA, "incompatible") { + inA, inB := Contains(rawA, "+incompatible"), Contains(rawB, "+incompatible") + if inA && !inB { return -1 } - if Contains(rawB, "incompatible") { + if !inA && inB { return 1 } + return 0 } diff --git a/text/gstr/gstr_z_unit_version_test.go b/text/gstr/gstr_z_unit_version_test.go index 77cefa5a3..88ebb7bf5 100644 --- a/text/gstr/gstr_z_unit_version_test.go +++ b/text/gstr/gstr_z_unit_version_test.go @@ -55,11 +55,26 @@ func Test_CompareVersionGo(t *testing.T) { t.AssertEQ(gstr.CompareVersionGo("1.0.1", "v1.1.0"), -1) t.AssertEQ(gstr.CompareVersionGo("1.0.0", "v0.1.0"), 1) t.AssertEQ(gstr.CompareVersionGo("1.0.0", "v1.0.0"), 0) + t.AssertEQ(gstr.CompareVersionGo("1.0.0", "v1.0"), 0) t.AssertEQ(gstr.CompareVersionGo("v0.0.0-20190626092158-b2ccc519800e", "0.0.0-20190626092158"), 0) t.AssertEQ(gstr.CompareVersionGo("v0.0.0-20190626092159-b2ccc519800e", "0.0.0-20190626092158"), 1) - t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.0"), -1) - t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.1"), -1) - // Note that this comparison a < b. + + // Specially in Golang: + // "v1.12.2-0.20200413154443-b17e3a6804fa" < "v1.12.2" + // "v1.12.3-0.20200413154443-b17e3a6804fa" > "v1.12.2" t.AssertEQ(gstr.CompareVersionGo("v1.12.2-0.20200413154443-b17e3a6804fa", "v1.12.2"), -1) + t.AssertEQ(gstr.CompareVersionGo("v1.12.2", "v1.12.2-0.20200413154443-b17e3a6804fa"), 1) + t.AssertEQ(gstr.CompareVersionGo("v1.12.3-0.20200413154443-b17e3a6804fa", "v1.12.2"), 1) + t.AssertEQ(gstr.CompareVersionGo("v1.12.2", "v1.12.3-0.20200413154443-b17e3a6804fa"), -1) + t.AssertEQ(gstr.CompareVersionGo("v1.12.2-0.20200413154443-b17e3a6804fa", "v0.0.0-20190626092158-b2ccc519800e"), 1) + t.AssertEQ(gstr.CompareVersionGo("v1.12.2-0.20200413154443-b17e3a6804fa", "v1.12.2-0.20200413154444-b2ccc519800e"), -1) + + // Specially in Golang: + // "v4.20.1+incompatible" < "v4.20.1" + t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.0"), -1) + t.AssertEQ(gstr.CompareVersionGo("4.20.0", "v4.20.0+incompatible"), 1) + t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.1"), -1) + t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "v4.20.0+incompatible"), 0) + }) }