From 80d11022b58acf5be3c1bac9ff49b5aa4bb5fd98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=8F=AF?= Date: Fri, 6 Sep 2024 09:51:05 +0800 Subject: [PATCH] refactor: example and log --- example_test.go | 45 +++++++++++++++++++++++++----- internal/kslog/log_observer.go | 10 +++---- testing.go | 8 +++++- tests/case1/case_lazy_init_test.go | 8 +++--- tests/case1/case_log_file_test.go | 2 +- tests/case1/case_log_level_test.go | 2 +- tests/case1/case_log_mock_test.go | 2 +- 7 files changed, 56 insertions(+), 21 deletions(-) diff --git a/example_test.go b/example_test.go index a425052..2945beb 100644 --- a/example_test.go +++ b/example_test.go @@ -11,10 +11,10 @@ import ( "github.com/go-kod/kod/interceptor/kmetric" "github.com/go-kod/kod/interceptor/krecovery" "github.com/go-kod/kod/interceptor/ktrace" - "github.com/go-kod/kod/internal/kslog" "go.uber.org/mock/gomock" ) +// This example demonstrates how to use [kod.Run] and [kod.Implements] to run a simple application. func Example_mainComponent() { kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { fmt.Println("Hello, World!") @@ -26,6 +26,7 @@ func Example_mainComponent() { // helloWorld shutdown } +// This example demonstrates how to use [kod.Ref] to reference a component and call a method on it. func Example_componentRefAndCall() { kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { app.HelloWorld.Get().SayHello(ctx) @@ -37,6 +38,7 @@ func Example_componentRefAndCall() { // helloWorld shutdown } +// This example demonstrates how to use [kod.LazyInit] to defer component initialization until it is needed. func Example_componentLazyInit() { kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { app.HelloLazy.Get().SayHello(ctx) @@ -52,6 +54,7 @@ func Example_componentLazyInit() { // helloWorld shutdown } +// This example demonstrates how to use [kod.WithFakes] and [kod.Fake] to provide a mock implementation of a component. func Example_componentMock() { mock := helloworld.NewMockHelloWorld(gomock.NewController(nil)) mock.EXPECT().SayHello(gomock.Any()).Return() @@ -65,21 +68,33 @@ func Example_componentMock() { // Nothing printed from mock } +// This example demonstrates how to use [kod.WithConfig] to provide a configuration to the application. func Example_config() { kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { - fmt.Println(app.Config().Name) app.HelloWorld.Get().SayHello(ctx) return nil }, kod.WithConfigFile("./examples/helloworld/config.toml")) // Output: // helloWorld init - // globalConfig // Hello, World!config // helloWorld shutdown } +// This example demonstrates how to use [kod.WithGlobalConfig] to provide a global configuration to the application. +func Example_configGlobal() { + kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { + fmt.Println(app.Config().Name) + return nil + }, kod.WithConfigFile("./examples/helloworld/config.toml")) + // Output: + // helloWorld init + // globalConfig + // helloWorld shutdown +} + +// This example demonstrates how to use [kod.WithLogger] to provide a custom logger to the application. func Example_log() { - logger, observer := kslog.NewTestLogger() + logger, observer := kod.NewTestLogger() kod.RunTest(&testing.T{}, func(ctx context.Context, app *helloworld.App) { app.L(ctx).Debug("Hello, World!") @@ -100,6 +115,7 @@ func Example_log() { // {"level":"INFO","msg":"Hello, World!","component":"github.com/go-kod/kod/examples/helloworld/HelloWorld"} } +// This example demonstrates how to use [kod.WithInterceptors] to provide a custom interceptor to the application. func Example_interceptor() { interceptor := interceptor.Interceptor(func(ctx context.Context, info interceptor.CallInfo, req, res []interface{}, next interceptor.HandleFunc) error { fmt.Println("Before call") @@ -120,6 +136,8 @@ func Example_interceptor() { // helloWorld shutdown } +// This example demonstrates how to use built-in interceptors +// Such as [krecovery.Interceptor], [ktrace.Interceptor], and [kmetric.Interceptor] ... func Example_interceptorBuiltin() { kod.Run(context.Background(), func(ctx context.Context, app *helloworld.App) error { app.HelloWorld.Get().SayHello(ctx) @@ -131,6 +149,7 @@ func Example_interceptorBuiltin() { // helloWorld shutdown } +// This example demonstrates how to use [kod.RunTest] to run a test function. func Example_test() { kod.RunTest(&testing.T{}, func(ctx context.Context, app *helloworld.App) { app.HelloWorld.Get().SayHello(ctx) @@ -141,6 +160,7 @@ func Example_test() { // helloWorld shutdown } +// This example demonstrates how to use [kod.RunTest], [kod.Fake] and [kod.WithFakes] to run a test function with a mock component. func Example_testWithMockComponent() { mock := helloworld.NewMockHelloWorld(gomock.NewController(nil)) mock.EXPECT().SayHello(gomock.Any()).Return() @@ -153,6 +173,7 @@ func Example_testWithMockComponent() { // Nothing printed from mock } +// This example demonstrates how to use [kod.RunTest] and [kod.WithConfigFile] to run a test function with a configuration. func Example_testWithConfig() { kod.RunTest(&testing.T{}, func(ctx context.Context, app *helloworld.App) { fmt.Println(app.Config().Name) @@ -165,16 +186,26 @@ func Example_testWithConfig() { // helloWorld shutdown } -// Example_testWithLogObserver demonstrates how to test log output. +// This example demonstrates how to use [kod.RunTest], [kod.NewTestLogger] and [kod.WithLogger] to run a test function with a custom logger. func Example_testWithLogObserver() { - kod.RunTest(&testing.T{}, func(ctx context.Context, app *helloworld.App) { + logger, observer := kod.NewTestLogger() + + t := &testing.T{} + kod.RunTest(t, func(ctx context.Context, app *helloworld.App) { app.L(ctx).Debug("Hello, World!") app.L(ctx).Info("Hello, World!") app.L(ctx).Warn("Hello, World!") app.L(ctx).Error("Hello, World!") - }) + }, kod.WithLogger(logger)) + + fmt.Println(observer.Len()) + fmt.Println(observer.ErrorCount()) + fmt.Println(observer.Clean().Len()) // Output: // helloWorld init // helloWorld shutdown + // 3 + // 1 + // 0 } diff --git a/internal/kslog/log_observer.go b/internal/kslog/log_observer.go index 55b7ce5..c62a805 100644 --- a/internal/kslog/log_observer.go +++ b/internal/kslog/log_observer.go @@ -5,6 +5,8 @@ import ( "encoding/json" "log/slog" "strings" + + "github.com/samber/lo" ) // removeTime removes the top-level time attribute. @@ -31,9 +33,7 @@ func (b *observer) parse() []map[string]any { } var m map[string]any - if err := json.Unmarshal([]byte(line), &m); err != nil { - panic(err) - } + lo.Must0(json.Unmarshal([]byte(line), &m)) data = append(data, m) } @@ -69,9 +69,7 @@ func (b *observer) Filter(filter func(map[string]any) bool) *observer { buf := new(bytes.Buffer) for _, line := range filtered { - if err := json.NewEncoder(buf).Encode(line); err != nil { - panic(err) - } + lo.Must0(json.NewEncoder(buf).Encode(line)) } return &observer{ diff --git a/testing.go b/testing.go index b2704ed..cc9dd42 100644 --- a/testing.go +++ b/testing.go @@ -11,13 +11,16 @@ import ( "github.com/go-kod/kod/internal/kslog" ) -var NewTestObserver = kslog.NewTestLogger +// NewTestLogger returns a new test logger. +var NewTestLogger = kslog.NewTestLogger +// fakeComponent is a fake component. type fakeComponent struct { intf reflect.Type impl any } +// Fake returns a fake component. func Fake[T any](impl any) fakeComponent { t := reflect.TypeFor[T]() if _, ok := impl.(T); !ok { @@ -26,6 +29,7 @@ func Fake[T any](impl any) fakeComponent { return fakeComponent{intf: t, impl: impl} } +// options contains options for the runner. type runner struct { options []func(*options) } @@ -51,6 +55,7 @@ func RunTest3[T1, T2, T3 any](tb testing.TB, body func(context.Context, T1, T2, runTest(tb, body, opts...) } +// runTest runs a test function. func runTest(tb testing.TB, testBody any, opts ...func(*options)) { tb.Helper() @@ -61,6 +66,7 @@ func runTest(tb testing.TB, testBody any, opts ...func(*options)) { } } +// sub runs a test function. func (r runner) sub(tb testing.TB, testBody any) error { tb.Helper() diff --git a/tests/case1/case_lazy_init_test.go b/tests/case1/case_lazy_init_test.go index 8007b45..e86ab00 100644 --- a/tests/case1/case_lazy_init_test.go +++ b/tests/case1/case_lazy_init_test.go @@ -10,7 +10,7 @@ import ( ) func TestLazyInit(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest(t, func(ctx context.Context, k *lazyInitImpl) { require.Equal(t, 1, observer.Len(), observer.String()) @@ -28,7 +28,7 @@ func TestLazyInit(t *testing.T) { } func TestLazyInitTest(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest2(t, func(ctx context.Context, k *lazyInitImpl, comp *lazyInitComponent) { k.Try(ctx) @@ -42,7 +42,7 @@ func TestLazyInitTest(t *testing.T) { } func TestLazyInitTest2(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest2(t, func(ctx context.Context, k LazyInitImpl, comp LazyInitComponent) { require.Equal(t, 2, observer.Len(), observer.String()) @@ -54,7 +54,7 @@ func TestLazyInitTest2(t *testing.T) { } func TestLazyInitTest3(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest2(t, func(ctx context.Context, k *lazyInitImpl, comp LazyInitComponent) { k.Try(ctx) diff --git a/tests/case1/case_log_file_test.go b/tests/case1/case_log_file_test.go index d50cae0..10ae3a3 100644 --- a/tests/case1/case_log_file_test.go +++ b/tests/case1/case_log_file_test.go @@ -13,7 +13,7 @@ import ( ) func TestLogFile(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest(t, func(ctx context.Context, k Test1Component) { _, err := k.Foo(ctx, &FooReq{Id: 1}) diff --git a/tests/case1/case_log_level_test.go b/tests/case1/case_log_level_test.go index a7138b6..649ed09 100644 --- a/tests/case1/case_log_level_test.go +++ b/tests/case1/case_log_level_test.go @@ -10,7 +10,7 @@ import ( ) func TestLogLevel(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() kod.RunTest(t, func(ctx context.Context, k *test1Component) { observer.Clean() diff --git a/tests/case1/case_log_mock_test.go b/tests/case1/case_log_mock_test.go index cd1671b..32c33e2 100644 --- a/tests/case1/case_log_mock_test.go +++ b/tests/case1/case_log_mock_test.go @@ -11,7 +11,7 @@ import ( ) func TestMockLog(t *testing.T) { - log, observer := kod.NewTestObserver() + log, observer := kod.NewTestLogger() t.Setenv("KOD_LOG_LEVEL", "error") kod.RunTest(t, func(ctx context.Context, k Test1Component) {