From c9d345609fd9ac480257e040c240520e9b1c4a61 Mon Sep 17 00:00:00 2001 From: awatercolorpen Date: Sun, 26 Apr 2026 14:54:22 +0800 Subject: [PATCH 1/2] test: add coverage_boost_test.go to push main pkg coverage to 82.8% (Phase 3) --- coverage_boost_test.go | 156 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 coverage_boost_test.go diff --git a/coverage_boost_test.go b/coverage_boost_test.go new file mode 100644 index 0000000..97ad7ad --- /dev/null +++ b/coverage_boost_test.go @@ -0,0 +1,156 @@ +package olapsql_test + +// coverage_boost_test.go — Phase 3 coverage boost +// Targets: Clients.SetLogger, Clients.BuildSQL, Manager.SetLogger, Manager.BuildSQL, +// NewTranslator (direct-SQL path), FileAdapter.GetMetricsBySource/GetDimensionsBySource, +// database.getDialect unsupported-type error path. + +import ( + "testing" + + olapsql "github.com/awatercolorpen/olap-sql" + "github.com/awatercolorpen/olap-sql/api/types" + "github.com/stretchr/testify/assert" + "gorm.io/gorm/logger" +) + +// --------------------------------------------------------------------------- +// Clients.SetLogger +// --------------------------------------------------------------------------- + +func TestClients_SetLogger(t *testing.T) { + clients, err := newClients(t.TempDir()) + assert.NoError(t, err) + + // SetLogger should not panic; pass a no-op logger. + clients.SetLogger(logger.Discard) +} + +// --------------------------------------------------------------------------- +// Clients.BuildSQL +// --------------------------------------------------------------------------- + +func TestClients_BuildSQL(t *testing.T) { + m, err := newManager(t) + assert.NoError(t, err) + assert.NoError(t, MockLoad(m)) + + query := MockQuery1() + + dictionary, err := m.GetDictionary() + assert.NoError(t, err) + + clause, err := dictionary.Translate(query) + assert.NoError(t, err) + + clients, err := m.GetClients() + assert.NoError(t, err) + + sql, err := clients.BuildSQL(clause) + assert.NoError(t, err) + assert.NotEmpty(t, sql) +} + +// --------------------------------------------------------------------------- +// Manager.SetLogger +// --------------------------------------------------------------------------- + +func TestManager_SetLogger(t *testing.T) { + m, err := newManager(t) + assert.NoError(t, err) + + // Should silently succeed (logs go to Discard). + m.SetLogger(logger.Discard) +} + +// --------------------------------------------------------------------------- +// Manager.BuildSQL +// --------------------------------------------------------------------------- + +func TestManager_BuildSQL(t *testing.T) { + m, err := newManager(t) + assert.NoError(t, err) + assert.NoError(t, MockLoad(m)) + + query := MockQuery1() + sql, err := m.BuildSQL(query) + assert.NoError(t, err) + assert.NotEmpty(t, sql) +} + +// --------------------------------------------------------------------------- +// NewTranslator — direct-SQL path (query.Sql != "") +// --------------------------------------------------------------------------- + +func TestNewTranslator_DirectSQL(t *testing.T) { + dict, err := newDictionary() + assert.NoError(t, err) + + query := &types.Query{ + DataSetName: mockWikiStatDataSet, + Sql: "SELECT 1", + } + + sql, err := dict.Translate(query) + assert.NoError(t, err) + assert.NotNil(t, sql) +} + +// --------------------------------------------------------------------------- +// FileAdapter.GetMetricsBySource / GetDimensionsBySource +// --------------------------------------------------------------------------- + +func TestFileAdapter_GetMetricsBySource(t *testing.T) { + adapter, err := newFileAdapter() + assert.NoError(t, err) + + // "wikistat" is a known source in the test dictionary. + metrics := adapter.GetMetricsBySource("wikistat") + assert.NotEmpty(t, metrics, "expected at least one metric for source 'wikistat'") + + // Non-existent source should return empty slice (not an error). + none := adapter.GetMetricsBySource("__nonexistent__") + assert.Empty(t, none) +} + +func TestFileAdapter_GetDimensionsBySource(t *testing.T) { + adapter, err := newFileAdapter() + assert.NoError(t, err) + + dims := adapter.GetDimensionsBySource("wikistat") + assert.NotEmpty(t, dims, "expected at least one dimension for source 'wikistat'") + + none := adapter.GetDimensionsBySource("__nonexistent__") + assert.Empty(t, none) +} + +// --------------------------------------------------------------------------- +// DBOption.NewDB — unsupported type returns error +// --------------------------------------------------------------------------- + +func TestDBOption_NewDB_UnsupportedType(t *testing.T) { + opt := &olapsql.DBOption{ + DSN: "whatever", + Type: types.DBType("__unknown__"), + } + _, err := opt.NewDB() + assert.Error(t, err) + assert.Contains(t, err.Error(), "unsupported db type") +} + +// --------------------------------------------------------------------------- +// helpers +// --------------------------------------------------------------------------- + +func newDictionary() (*olapsql.Dictionary, error) { + do := getDictionaryOption() + return olapsql.NewDictionary(do) +} + +func newFileAdapter() (olapsql.IAdapter, error) { + opt := &olapsql.AdapterOption{ + Type: olapsql.FILEAdapter, + Dsn: "test/dictionary.sqlite.toml", + } + return olapsql.NewAdapter(opt) +} From 56d672f0d71e61e41de32618eff1683aec8e04e1 Mon Sep 17 00:00:00 2001 From: awatercolorpen Date: Tue, 28 Apr 2026 14:54:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?test:=20address=20PR=20review=20=E2=80=94?= =?UTF-8?q?=20remove=20dead=20MockLoad=20in=20TestClients=5FBuildSQL,=20st?= =?UTF-8?q?rengthen=20TestNewTranslator=5FDirectSQL=20assertion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coverage_boost_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/coverage_boost_test.go b/coverage_boost_test.go index 97ad7ad..3fb6f2b 100644 --- a/coverage_boost_test.go +++ b/coverage_boost_test.go @@ -31,9 +31,9 @@ func TestClients_SetLogger(t *testing.T) { // --------------------------------------------------------------------------- func TestClients_BuildSQL(t *testing.T) { + // BuildSQL uses DryRun mode, so no data loading is required. m, err := newManager(t) assert.NoError(t, err) - assert.NoError(t, MockLoad(m)) query := MockQuery1() @@ -46,9 +46,9 @@ func TestClients_BuildSQL(t *testing.T) { clients, err := m.GetClients() assert.NoError(t, err) - sql, err := clients.BuildSQL(clause) + sqlStr, err := clients.BuildSQL(clause) assert.NoError(t, err) - assert.NotEmpty(t, sql) + assert.NotEmpty(t, sqlStr) } // --------------------------------------------------------------------------- @@ -91,9 +91,14 @@ func TestNewTranslator_DirectSQL(t *testing.T) { Sql: "SELECT 1", } - sql, err := dict.Translate(query) + clause, err := dict.Translate(query) assert.NoError(t, err) - assert.NotNil(t, sql) + assert.NotNil(t, clause) + + // Verify the direct-SQL path preserved the raw SQL string. + sqlClause, ok := clause.(*types.SqlClause) + assert.True(t, ok, "expected clause to be *types.SqlClause") + assert.Equal(t, "SELECT 1", sqlClause.Sql) } // ---------------------------------------------------------------------------