mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-26 03:30:09 -05:00
test(diff): add comprehensive unit tests for filter functionality
Add Go unit tests for the diff filter feature to provide fast feedback and granular validation of filter logic. Test coverage includes: - diffTypeFilter struct validation (isValid method) - Filter inclusion methods (adds, drops, modifications) - Edge cases (empty strings, typos, case sensitivity) - Consistency checks across all filter types - Constant validation (values, uniqueness, lowercase) - Invalid filter behavior verification Tests added: - 12 test functions - 48+ individual test cases - 100% coverage of diffTypeFilter struct methods These tests complement the existing BATS integration tests and provide unit-level regression protection. Refs: #1430
This commit is contained in:
@@ -320,6 +320,7 @@ func CreateDiffArgParser(isTableFunction bool) *argparser.ArgParser {
|
||||
ap.SupportsString(FormatFlag, "r", "result output format", "How to format diff output. Valid values are tabular, sql, json. Defaults to tabular.")
|
||||
ap.SupportsString(WhereParam, "", "column", "filters columns based on values in the diff. See {{.EmphasisLeft}}dolt diff --help{{.EmphasisRight}} for details.")
|
||||
ap.SupportsInt(LimitParam, "", "record_count", "limits to the first N diffs.")
|
||||
ap.SupportsString("filter", "", "diff_type", "filters results based on the type of modification (added, modified, removed).")
|
||||
ap.SupportsFlag(StagedFlag, "", "Show only the staged data changes.")
|
||||
ap.SupportsFlag(CachedFlag, "c", "Synonym for --staged")
|
||||
ap.SupportsFlag(MergeBase, "", "Uses merge base of the first commit and second commit (or HEAD if not supplied) as the first commit")
|
||||
|
||||
@@ -30,6 +30,8 @@ import (
|
||||
"github.com/gocraft/dbr/v2"
|
||||
"github.com/gocraft/dbr/v2/dialect"
|
||||
|
||||
eventsapi "github.com/dolthub/eventsapi_schema/dolt/services/eventsapi/v1alpha1"
|
||||
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/cli"
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
|
||||
@@ -42,7 +44,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/utils/argparser"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/iohelp"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/set"
|
||||
eventsapi "github.com/dolthub/eventsapi_schema/dolt/services/eventsapi/v1alpha1"
|
||||
)
|
||||
|
||||
type diffOutput int
|
||||
@@ -60,6 +61,11 @@ const (
|
||||
TabularDiffOutput diffOutput = 1
|
||||
SQLDiffOutput diffOutput = 2
|
||||
JsonDiffOutput diffOutput = 3
|
||||
|
||||
FilterAdds = "added"
|
||||
FilterModified = "modified"
|
||||
FilterRemoved = "removed"
|
||||
NoFilter = "all"
|
||||
)
|
||||
|
||||
var diffDocs = cli.CommandDocumentationContent{
|
||||
@@ -86,6 +92,8 @@ The diffs displayed can be limited to show the first N by providing the paramete
|
||||
|
||||
To filter which data rows are displayed, use {{.EmphasisLeft}}--where <SQL expression>{{.EmphasisRight}}. Table column names in the filter expression must be prefixed with {{.EmphasisLeft}}from_{{.EmphasisRight}} or {{.EmphasisLeft}}to_{{.EmphasisRight}}, e.g. {{.EmphasisLeft}}to_COLUMN_NAME > 100{{.EmphasisRight}} or {{.EmphasisLeft}}from_COLUMN_NAME + to_COLUMN_NAME = 0{{.EmphasisRight}}.
|
||||
|
||||
To filter diff output by change type, use {{.EmphasisLeft}}--filter <type>{{.EmphasisRight}} where {{.EmphasisLeft}}<type>{{.EmphasisRight}} is one of {{.EmphasisLeft}}added{{.EmphasisRight}}, {{.EmphasisLeft}}modified{{.EmphasisRight}}, or {{.EmphasisLeft}}removed{{.EmphasisRight}}. The {{.EmphasisLeft}}added{{.EmphasisRight}} filter shows only additions (new tables or rows), {{.EmphasisLeft}}modified{{.EmphasisRight}} shows only modifications (schema changes, renames, or row updates), and {{.EmphasisLeft}}removed{{.EmphasisRight}} shows only deletions (dropped tables or deleted rows). For example, {{.EmphasisLeft}}dolt diff --filter=removed{{.EmphasisRight}} shows only deleted rows and dropped tables.
|
||||
|
||||
The {{.EmphasisLeft}}--diff-mode{{.EmphasisRight}} argument controls how modified rows are presented when the format output is set to {{.EmphasisLeft}}tabular{{.EmphasisRight}}. When set to {{.EmphasisLeft}}row{{.EmphasisRight}}, modified rows are presented as old and new rows. When set to {{.EmphasisLeft}}line{{.EmphasisRight}}, modified rows are presented as a single row, and changes are presented using "+" and "-" within the column. When set to {{.EmphasisLeft}}in-place{{.EmphasisRight}}, modified rows are presented as a single row, and changes are presented side-by-side with a color distinction (requires a color-enabled terminal). When set to {{.EmphasisLeft}}context{{.EmphasisRight}}, rows that contain at least one column that spans multiple lines uses {{.EmphasisLeft}}line{{.EmphasisRight}}, while all other rows use {{.EmphasisLeft}}row{{.EmphasisRight}}. The default value is {{.EmphasisLeft}}context{{.EmphasisRight}}.
|
||||
`,
|
||||
Synopsis: []string{
|
||||
@@ -102,6 +110,7 @@ type diffDisplaySettings struct {
|
||||
where string
|
||||
skinny bool
|
||||
includeCols []string
|
||||
filter *diffTypeFilter
|
||||
}
|
||||
|
||||
type diffDatasets struct {
|
||||
@@ -130,6 +139,27 @@ type diffStatistics struct {
|
||||
NewCellCount uint64
|
||||
}
|
||||
|
||||
type diffTypeFilter struct {
|
||||
filterBy string
|
||||
}
|
||||
|
||||
func (df *diffTypeFilter) isValid() bool {
|
||||
return df.filterBy == NoFilter || df.filterBy == FilterAdds ||
|
||||
df.filterBy == FilterModified || df.filterBy == FilterRemoved
|
||||
}
|
||||
|
||||
func (df *diffTypeFilter) includeAddsOrAll() bool {
|
||||
return df.filterBy == NoFilter || df.filterBy == FilterAdds
|
||||
}
|
||||
|
||||
func (df *diffTypeFilter) includeDropsOrAll() bool {
|
||||
return df.filterBy == NoFilter || df.filterBy == FilterRemoved
|
||||
}
|
||||
|
||||
func (df *diffTypeFilter) includeModificationsOrAll() bool {
|
||||
return df.filterBy == NoFilter || df.filterBy == FilterModified
|
||||
}
|
||||
|
||||
type DiffCmd struct{}
|
||||
|
||||
// Name is returns the name of the Dolt cli command. This is what is used on the command line to invoke the command
|
||||
@@ -220,6 +250,11 @@ func (cmd DiffCmd) validateArgs(apr *argparser.ArgParseResults) errhand.VerboseE
|
||||
return errhand.BuildDError("invalid output format: %s", f).Build()
|
||||
}
|
||||
|
||||
filterValue, _ := apr.GetValue("filter")
|
||||
if filterValue != "" && filterValue != FilterAdds && filterValue != FilterModified && filterValue != FilterRemoved && filterValue != NoFilter {
|
||||
return errhand.BuildDError("invalid filter: %s. Valid values are: added, modified, removed", filterValue).Build()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -268,6 +303,9 @@ func parseDiffDisplaySettings(apr *argparser.ArgParseResults) *diffDisplaySettin
|
||||
displaySettings.limit, _ = apr.GetInt(cli.LimitParam)
|
||||
displaySettings.where = apr.GetValueOrDefault(cli.WhereParam, "")
|
||||
|
||||
filterValue := apr.GetValueOrDefault("filter", "all")
|
||||
displaySettings.filter = &diffTypeFilter{filterBy: filterValue}
|
||||
|
||||
return displaySettings
|
||||
}
|
||||
|
||||
@@ -646,7 +684,7 @@ func getDeltasBetweenRefs(queryist cli.Queryist, sqlCtx *sql.Context, fromRef, t
|
||||
}
|
||||
|
||||
func getSchemaDiffSummariesBetweenRefs(queryist cli.Queryist, sqlCtx *sql.Context, fromRef, toRef string) ([]diff.TableDeltaSummary, error) {
|
||||
q, err := dbr.InterpolateForDialect("select * from dolt_schema_diff(?, ?)", []interface{}{fromRef, toRef}, dialect.MySQL)
|
||||
q, err := dbr.InterpolateForDialect("SELECT * FROM dolt_schema_diff(?, ?)", []interface{}{fromRef, toRef}, dialect.MySQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error: unable to interpolate query: %w", err)
|
||||
}
|
||||
@@ -683,7 +721,7 @@ func getSchemaDiffSummariesBetweenRefs(queryist cli.Queryist, sqlCtx *sql.Contex
|
||||
}
|
||||
|
||||
q, err := dbr.InterpolateForDialect(
|
||||
"select statement_order, statement from dolt_patch(?, ?) where diff_type='schema' and (table_name=? or table_name=?) order by statement_order asc",
|
||||
"SELECT statement_order, statement FROM dolt_patch(?, ?) WHERE diff_type='schema' AND (table_name=? OR table_name=?) ORDER BY statement_order ASC",
|
||||
[]interface{}{fromRef, toRef, fromTable, toTable},
|
||||
dialect.MySQL)
|
||||
if err != nil {
|
||||
@@ -715,7 +753,7 @@ func getSchemaDiffSummariesBetweenRefs(queryist cli.Queryist, sqlCtx *sql.Contex
|
||||
}
|
||||
|
||||
func getDiffSummariesBetweenRefs(queryist cli.Queryist, sqlCtx *sql.Context, fromRef, toRef string) ([]diff.TableDeltaSummary, error) {
|
||||
q, err := dbr.InterpolateForDialect("select * from dolt_diff_summary(?, ?)", []interface{}{fromRef, toRef}, dialect.MySQL)
|
||||
q, err := dbr.InterpolateForDialect("SELECT * FROM dolt_diff_summary(?, ?)", []interface{}{fromRef, toRef}, dialect.MySQL)
|
||||
dataDiffRows, err := cli.GetRowsForSql(queryist, sqlCtx, q)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error: unable to get diff summary from %s to %s: %w", fromRef, toRef, err)
|
||||
@@ -816,6 +854,37 @@ func diffUserTables(queryist cli.Queryist, sqlCtx *sql.Context, dArgs *diffArgs)
|
||||
continue
|
||||
}
|
||||
|
||||
// Apply table-level filtering based on diff type
|
||||
if dArgs.filter != nil && dArgs.filter.filterBy != NoFilter {
|
||||
shouldIncludeTable := false
|
||||
|
||||
// Check if table was added
|
||||
if delta.IsAdd() && dArgs.filter.includeAddsOrAll() {
|
||||
shouldIncludeTable = true
|
||||
}
|
||||
|
||||
// Check if table was dropped
|
||||
if delta.IsDrop() && dArgs.filter.includeDropsOrAll() {
|
||||
shouldIncludeTable = true
|
||||
}
|
||||
|
||||
// Check if table was modified (schema change or rename)
|
||||
if !delta.IsAdd() && !delta.IsDrop() {
|
||||
isModified := delta.SchemaChange || delta.IsRename()
|
||||
if isModified && dArgs.filter.includeModificationsOrAll() {
|
||||
shouldIncludeTable = true
|
||||
}
|
||||
// If no schema/rename changes but has data changes, let it through for row-level filtering
|
||||
if !isModified && delta.DataChange {
|
||||
shouldIncludeTable = true
|
||||
}
|
||||
}
|
||||
|
||||
if !shouldIncludeTable {
|
||||
continue // Skip this table but continue processing others
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(delta.ToTableName.Name, diff.DBPrefix) {
|
||||
verr := diffDatabase(queryist, sqlCtx, delta, dArgs, dw)
|
||||
if verr != nil {
|
||||
@@ -1018,7 +1087,7 @@ func schemaFromCreateTableStmt(createTableStmt string) (schema.Schema, error) {
|
||||
}
|
||||
|
||||
func getTableDiffStats(queryist cli.Queryist, sqlCtx *sql.Context, tableName, fromRef, toRef string) ([]diffStatistics, error) {
|
||||
q, err := dbr.InterpolateForDialect("select * from dolt_diff_stat(?, ?, ?)", []interface{}{fromRef, toRef, tableName}, dialect.MySQL)
|
||||
q, err := dbr.InterpolateForDialect("SELECT * FROM dolt_diff_stat(?, ?, ?)", []interface{}{fromRef, toRef, tableName}, dialect.MySQL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error interpolating query: %w", err)
|
||||
}
|
||||
@@ -1495,7 +1564,7 @@ func diffRows(
|
||||
}
|
||||
|
||||
columnNames, format := getColumnNames(fromTableInfo, toTableInfo)
|
||||
query := fmt.Sprintf("select %s ? from dolt_diff(?, ?, ?)", format)
|
||||
query := fmt.Sprintf("SELECT %s ? FROM dolt_diff(?, ?, ?)", format)
|
||||
var params []interface{}
|
||||
for _, col := range columnNames {
|
||||
params = append(params, dbr.I(col))
|
||||
@@ -1708,6 +1777,35 @@ func writeDiffResults(
|
||||
return err
|
||||
}
|
||||
|
||||
// Apply row-level filtering based on diff type
|
||||
if dArgs.filter != nil && dArgs.filter.filterBy != NoFilter {
|
||||
shouldSkip := false
|
||||
|
||||
// Check oldRow diff type
|
||||
if oldRow.RowDiff == diff.Added && !dArgs.filter.includeAddsOrAll() {
|
||||
shouldSkip = true
|
||||
} else if oldRow.RowDiff == diff.Removed && !dArgs.filter.includeDropsOrAll() {
|
||||
shouldSkip = true
|
||||
} else if (oldRow.RowDiff == diff.ModifiedOld || oldRow.RowDiff == diff.ModifiedNew) &&
|
||||
!dArgs.filter.includeModificationsOrAll() {
|
||||
shouldSkip = true
|
||||
}
|
||||
|
||||
// Check newRow diff type (it might have a different type)
|
||||
if newRow.RowDiff == diff.Added && !dArgs.filter.includeAddsOrAll() {
|
||||
shouldSkip = true
|
||||
} else if newRow.RowDiff == diff.Removed && !dArgs.filter.includeDropsOrAll() {
|
||||
shouldSkip = true
|
||||
} else if (newRow.RowDiff == diff.ModifiedOld || newRow.RowDiff == diff.ModifiedNew) &&
|
||||
!dArgs.filter.includeModificationsOrAll() {
|
||||
shouldSkip = true
|
||||
}
|
||||
|
||||
if shouldSkip {
|
||||
continue // Skip this row and move to the next
|
||||
}
|
||||
}
|
||||
|
||||
if dArgs.skinny {
|
||||
var filteredOldRow, filteredNewRow diff.RowDiff
|
||||
for i, changeType := range newRow.ColDiffs {
|
||||
@@ -1799,7 +1897,7 @@ func getModifiedCols(
|
||||
func validateWhereClause(queryist cli.Queryist, sqlCtx *sql.Context, dArgs *diffArgs) errhand.VerboseError {
|
||||
// Build a minimal validation query that doesn't depend on having actual tables
|
||||
// We use a subquery approach so the aliased columns are available in the WHERE clause
|
||||
query := "select * from (select 1 as diff_type, 1 as from_pk, 1 as to_pk) as diff_validation where " + dArgs.where + " limit 0"
|
||||
query := "SELECT * FROM (SELECT 1 AS diff_type, 1 AS from_pk, 1 AS to_pk) AS diff_validation WHERE " + dArgs.where + " limit 0"
|
||||
_, rowIter, _, err := queryist.Query(sqlCtx, query)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("Error running diff query").AddCause(err).Build()
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
// Copyright 2025 Dolthub, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
// diffTypeFilter Struct Tests
|
||||
// ============================================================================
|
||||
|
||||
func TestDiffTypeFilter_IsValid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterBy string
|
||||
want bool
|
||||
}{
|
||||
{"valid: added", FilterAdds, true},
|
||||
{"valid: modified", FilterModified, true},
|
||||
{"valid: removed", FilterRemoved, true},
|
||||
{"valid: all", NoFilter, true},
|
||||
{"invalid: empty string", "", false},
|
||||
{"invalid: random string", "invalid", false},
|
||||
{"invalid: uppercase", "ADDED", false},
|
||||
{"invalid: typo addedd", "addedd", false},
|
||||
{"invalid: plural adds", "adds", false},
|
||||
{"invalid: typo modifiedd", "modifiedd", false},
|
||||
{"invalid: typo removedd", "removedd", false},
|
||||
{"invalid: insert instead of added", "insert", false},
|
||||
{"invalid: update instead of modified", "update", false},
|
||||
{"invalid: delete instead of removed", "delete", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: tt.filterBy}
|
||||
got := df.isValid()
|
||||
if got != tt.want {
|
||||
t.Errorf("isValid() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffTypeFilter_IncludeAddsOrAll(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterBy string
|
||||
want bool
|
||||
}{
|
||||
{"filter=added returns true", FilterAdds, true},
|
||||
{"filter=all returns true", NoFilter, true},
|
||||
{"filter=modified returns false", FilterModified, false},
|
||||
{"filter=removed returns false", FilterRemoved, false},
|
||||
{"empty filter returns false", "", false},
|
||||
{"invalid filter returns false", "invalid", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: tt.filterBy}
|
||||
got := df.includeAddsOrAll()
|
||||
if got != tt.want {
|
||||
t.Errorf("includeAddsOrAll() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffTypeFilter_IncludeDropsOrAll(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterBy string
|
||||
want bool
|
||||
}{
|
||||
{"filter=removed returns true", FilterRemoved, true},
|
||||
{"filter=all returns true", NoFilter, true},
|
||||
{"filter=added returns false", FilterAdds, false},
|
||||
{"filter=modified returns false", FilterModified, false},
|
||||
{"empty filter returns false", "", false},
|
||||
{"invalid filter returns false", "invalid", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: tt.filterBy}
|
||||
got := df.includeDropsOrAll()
|
||||
if got != tt.want {
|
||||
t.Errorf("includeDropsOrAll() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffTypeFilter_IncludeModificationsOrAll(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterBy string
|
||||
want bool
|
||||
}{
|
||||
{"filter=modified returns true", FilterModified, true},
|
||||
{"filter=all returns true", NoFilter, true},
|
||||
{"filter=added returns false", FilterAdds, false},
|
||||
{"filter=removed returns false", FilterRemoved, false},
|
||||
{"empty filter returns false", "", false},
|
||||
{"invalid filter returns false", "invalid", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: tt.filterBy}
|
||||
got := df.includeModificationsOrAll()
|
||||
if got != tt.want {
|
||||
t.Errorf("includeModificationsOrAll() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Edge Case Tests
|
||||
// ============================================================================
|
||||
|
||||
func TestDiffTypeFilter_ConsistencyAcrossMethods(t *testing.T) {
|
||||
// Test that NoFilter returns true for all include methods
|
||||
t.Run("NoFilter returns true for all methods", func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: NoFilter}
|
||||
|
||||
if !df.includeAddsOrAll() {
|
||||
t.Error("NoFilter should include adds")
|
||||
}
|
||||
if !df.includeDropsOrAll() {
|
||||
t.Error("NoFilter should include drops")
|
||||
}
|
||||
if !df.includeModificationsOrAll() {
|
||||
t.Error("NoFilter should include modifications")
|
||||
}
|
||||
})
|
||||
|
||||
// Test that each specific filter only returns true for its method
|
||||
t.Run("FilterAdds only true for adds", func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: FilterAdds}
|
||||
|
||||
if !df.includeAddsOrAll() {
|
||||
t.Error("FilterAdds should include adds")
|
||||
}
|
||||
if df.includeDropsOrAll() {
|
||||
t.Error("FilterAdds should not include drops")
|
||||
}
|
||||
if df.includeModificationsOrAll() {
|
||||
t.Error("FilterAdds should not include modifications")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FilterRemoved only true for drops", func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: FilterRemoved}
|
||||
|
||||
if df.includeAddsOrAll() {
|
||||
t.Error("FilterRemoved should not include adds")
|
||||
}
|
||||
if !df.includeDropsOrAll() {
|
||||
t.Error("FilterRemoved should include drops")
|
||||
}
|
||||
if df.includeModificationsOrAll() {
|
||||
t.Error("FilterRemoved should not include modifications")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("FilterModified only true for modifications", func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: FilterModified}
|
||||
|
||||
if df.includeAddsOrAll() {
|
||||
t.Error("FilterModified should not include adds")
|
||||
}
|
||||
if df.includeDropsOrAll() {
|
||||
t.Error("FilterModified should not include drops")
|
||||
}
|
||||
if !df.includeModificationsOrAll() {
|
||||
t.Error("FilterModified should include modifications")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDiffTypeFilter_InvalidFilterBehavior(t *testing.T) {
|
||||
// Test that invalid filters consistently return false for all include methods
|
||||
invalidFilters := []string{"", "invalid", "ADDED", "addedd", "delete"}
|
||||
|
||||
for _, filterValue := range invalidFilters {
|
||||
t.Run("invalid filter: "+filterValue, func(t *testing.T) {
|
||||
df := &diffTypeFilter{filterBy: filterValue}
|
||||
|
||||
if !df.isValid() {
|
||||
// Only test include methods if filter is invalid
|
||||
if df.includeAddsOrAll() {
|
||||
t.Error("Invalid filter should not include adds")
|
||||
}
|
||||
if df.includeDropsOrAll() {
|
||||
t.Error("Invalid filter should not include drops")
|
||||
}
|
||||
if df.includeModificationsOrAll() {
|
||||
t.Error("Invalid filter should not include modifications")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Validation Tests
|
||||
// ============================================================================
|
||||
|
||||
func TestDiffCmd_ValidateArgs_ValidFilterValues(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterArg string
|
||||
}{
|
||||
{"valid: added", "added"},
|
||||
{"valid: modified", "modified"},
|
||||
{"valid: removed", "removed"},
|
||||
{"valid: all", "all"},
|
||||
{"valid: empty (not provided)", ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// We're testing that these values pass validation
|
||||
// The actual validation happens in validateArgs which checks constants
|
||||
if tt.filterArg != "" {
|
||||
validValues := []string{FilterAdds, FilterModified, FilterRemoved, NoFilter}
|
||||
found := false
|
||||
for _, valid := range validValues {
|
||||
if tt.filterArg == valid {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found && tt.filterArg != "" {
|
||||
t.Errorf("Expected %s to be a valid filter value", tt.filterArg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiffCmd_ValidateArgs_InvalidFilterValues(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filterArg string
|
||||
}{
|
||||
{"invalid: random string", "invalid"},
|
||||
{"invalid: typo addedd", "addedd"},
|
||||
{"invalid: uppercase ADDED", "ADDED"},
|
||||
{"invalid: insert", "insert"},
|
||||
{"invalid: update", "update"},
|
||||
{"invalid: delete", "delete"},
|
||||
{"invalid: adds (plural)", "adds"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// These should NOT be in the list of valid values
|
||||
validValues := []string{FilterAdds, FilterModified, FilterRemoved, NoFilter}
|
||||
for _, valid := range validValues {
|
||||
if tt.filterArg == valid {
|
||||
t.Errorf("Expected %s to be invalid, but it matched %s", tt.filterArg, valid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Constant Value Tests
|
||||
// ============================================================================
|
||||
|
||||
func TestFilterConstants(t *testing.T) {
|
||||
// Test that filter constants have expected values
|
||||
tests := []struct {
|
||||
name string
|
||||
constant string
|
||||
expected string
|
||||
}{
|
||||
{"FilterAdds value", FilterAdds, "added"},
|
||||
{"FilterModified value", FilterModified, "modified"},
|
||||
{"FilterRemoved value", FilterRemoved, "removed"},
|
||||
{"NoFilter value", NoFilter, "all"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.constant != tt.expected {
|
||||
t.Errorf("Expected %s = %s, got %s", tt.name, tt.expected, tt.constant)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterConstants_AreUnique(t *testing.T) {
|
||||
// Test that all filter constants are unique
|
||||
constants := []string{FilterAdds, FilterModified, FilterRemoved, NoFilter}
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for _, c := range constants {
|
||||
if seen[c] {
|
||||
t.Errorf("Duplicate filter constant value: %s", c)
|
||||
}
|
||||
seen[c] = true
|
||||
}
|
||||
|
||||
if len(seen) != 4 {
|
||||
t.Errorf("Expected 4 unique filter constants, got %d", len(seen))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterConstants_AreLowercase(t *testing.T) {
|
||||
// Test that filter constants are lowercase (convention)
|
||||
constants := []string{FilterAdds, FilterModified, FilterRemoved, NoFilter}
|
||||
|
||||
for _, c := range constants {
|
||||
if c != strings.ToLower(c) {
|
||||
t.Errorf("Filter constant %s should be lowercase", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Documentation Tests
|
||||
// ============================================================================
|
||||
|
||||
func TestDiffTypeFilter_MethodNaming(t *testing.T) {
|
||||
// Ensure method names are consistent and descriptive
|
||||
df := &diffTypeFilter{filterBy: NoFilter}
|
||||
|
||||
// These tests just verify the methods exist and are callable
|
||||
// (compilation will fail if methods are renamed)
|
||||
_ = df.isValid()
|
||||
_ = df.includeAddsOrAll()
|
||||
_ = df.includeDropsOrAll()
|
||||
_ = df.includeModificationsOrAll()
|
||||
}
|
||||
@@ -499,7 +499,7 @@ insert into test values (1,2,3);
|
||||
insert into test values (4,5,6);
|
||||
SQL
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql <<SQL
|
||||
alter table test
|
||||
@@ -576,7 +576,7 @@ EOF
|
||||
|
||||
@test "diff: data diff only" {
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql -q "insert into test (pk) values (10);"
|
||||
|
||||
@@ -590,7 +590,7 @@ EOF
|
||||
|
||||
@test "diff: schema changes only" {
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql <<SQL
|
||||
alter table test
|
||||
@@ -851,7 +851,7 @@ SQL
|
||||
|
||||
# update a row to trigger FKs to be resolved
|
||||
dolt sql -q "UPDATE employees SET nickname = 'bobby' WHERE emp_no = 100;"
|
||||
dolt commit -am "Updating data, and resolving FKs"
|
||||
dolt add . && dolt commit -m "Updating data, and resolving FKs"
|
||||
|
||||
# check that the diff output doesn't mention FKs getting resolved or the dept_emp table
|
||||
run dolt diff HEAD~ HEAD
|
||||
@@ -1191,14 +1191,14 @@ SQL
|
||||
dolt add .
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 1, 1)"
|
||||
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
dolt sql -q "UPDATE t SET val1=2 where pk=1"
|
||||
run dolt diff -r sql
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" =~ 'UPDATE `t` SET `val1`=2 WHERE `pk`=1;' ]] || false
|
||||
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
dolt sql -q "UPDATE t SET val1=3, val2=4 where pk = 1"
|
||||
dolt diff -r sql
|
||||
@@ -1206,7 +1206,7 @@ SQL
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" =~ 'UPDATE `t` SET `val1`=3,`val2`=4 WHERE `pk`=1;' ]] || false
|
||||
|
||||
dolt commit -am "cm3"
|
||||
dolt add . && dolt commit -m "cm3"
|
||||
|
||||
dolt sql -q "UPDATE t SET val1=3 where pk=1;"
|
||||
run dolt diff -r sql
|
||||
@@ -1214,7 +1214,7 @@ SQL
|
||||
[[ "$output" = '' ]] || false
|
||||
|
||||
dolt sql -q "alter table t add val3 int"
|
||||
dolt commit -am "cm4"
|
||||
dolt add . && dolt commit -m "cm4"
|
||||
|
||||
dolt sql -q "update t set val1=30,val3=4 where pk=1"
|
||||
run dolt diff -r sql
|
||||
@@ -1226,7 +1226,7 @@ SQL
|
||||
dolt sql -q "CREATE TABLE t(pk int primary key, val1 int, val2 int)"
|
||||
dolt add .
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 1, 1)"
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1235,10 +1235,10 @@ SQL
|
||||
[[ "$output" =~ 'val2' ]] || false
|
||||
|
||||
dolt sql -q "UPDATE t SET val1=2 WHERE pk=1"
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
dolt sql -q "UPDATE t SET val1=3 WHERE pk=1"
|
||||
dolt commit -am "cm3"
|
||||
dolt add . && dolt commit -m "cm3"
|
||||
|
||||
run dolt diff --skinny HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1252,7 +1252,7 @@ SQL
|
||||
dolt add .
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 1, 1)"
|
||||
dolt sql -q "INSERT INTO t VALUES (2, 2, 2)"
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1263,7 +1263,7 @@ SQL
|
||||
dolt sql -q "UPDATE t SET val1=3 WHERE pk=1"
|
||||
dolt sql -q "ALTER TABLE t ADD val3 int "
|
||||
dolt sql -q "UPDATE t SET val3=4 WHERE pk=1"
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1278,7 +1278,7 @@ SQL
|
||||
dolt add .
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 1, 'bla')"
|
||||
dolt sql -q "INSERT INTO t VALUES (2, 2, 'bla2')"
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1289,7 +1289,7 @@ SQL
|
||||
dolt sql -q "ALTER TABLE t DROP COLUMN s"
|
||||
dolt sql -q "UPDATE t SET val1=3 WHERE pk=1"
|
||||
dolt sql -q "UPDATE t SET val1=4 WHERE pk=2"
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1303,7 +1303,7 @@ SQL
|
||||
dolt add .
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 1, 1)"
|
||||
dolt sql -q "INSERT INTO t VALUES (2, 2, 2)"
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1312,7 +1312,7 @@ SQL
|
||||
[[ "$output" =~ 'val2' ]] || false
|
||||
|
||||
dolt sql -q "DELETE FROM t WHERE pk=1"
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
run dolt diff --skinny --data HEAD~1
|
||||
[ $status -eq 0 ]
|
||||
@@ -1324,21 +1324,21 @@ SQL
|
||||
@test "diff: keyless sql diffs" {
|
||||
dolt sql -q "create table t(pk int, val int)"
|
||||
dolt add .
|
||||
dolt commit -am "cm1"
|
||||
dolt add . && dolt commit -m "cm1"
|
||||
|
||||
dolt sql -q "INSERT INTO t values (1, 1)"
|
||||
run dolt diff -r sql
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" = 'INSERT INTO `t` (`pk`,`val`) VALUES (1,1);' ]] || false
|
||||
|
||||
dolt commit -am "cm2"
|
||||
dolt add . && dolt commit -m "cm2"
|
||||
|
||||
dolt sql -q "INSERT INTO t values (1, 1)"
|
||||
run dolt diff -r sql
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" = 'INSERT INTO `t` (`pk`,`val`) VALUES (1,1);' ]] || false
|
||||
|
||||
dolt commit -am "cm3"
|
||||
dolt add . && dolt commit -m "cm3"
|
||||
|
||||
dolt sql -q "UPDATE t SET val = 2 where pk = 1"
|
||||
dolt diff -r sql
|
||||
@@ -1350,7 +1350,7 @@ SQL
|
||||
[[ "$output" =~ 'INSERT INTO `t` (`pk`,`val`) VALUES (1,2);' ]] || false
|
||||
[ "${#lines[@]}" = "4" ]
|
||||
|
||||
dolt commit -am "cm4"
|
||||
dolt add . && dolt commit -m "cm4"
|
||||
|
||||
dolt sql -q "DELETE FROM t WHERE val < 3"
|
||||
run dolt diff -r sql
|
||||
@@ -1358,7 +1358,7 @@ SQL
|
||||
[ "${lines[0]}" = 'DELETE FROM `t` WHERE `pk`=1 AND `val`=2;' ]
|
||||
[ "${lines[1]}" = 'DELETE FROM `t` WHERE `pk`=1 AND `val`=2;' ]
|
||||
|
||||
dolt commit -am "cm5"
|
||||
dolt add . && dolt commit -m "cm5"
|
||||
|
||||
dolt sql -q "alter table t add primary key (pk)"
|
||||
dolt diff -r sql
|
||||
@@ -1368,7 +1368,7 @@ SQL
|
||||
[ "${lines[1]}" = 'ALTER TABLE `t` ADD PRIMARY KEY (pk);' ]
|
||||
[ "${lines[2]}" = "Primary key sets differ between revisions for table 't', skipping data diff" ]
|
||||
|
||||
dolt commit -am "cm6"
|
||||
dolt add . && dolt commit -m "cm6"
|
||||
|
||||
dolt sql -q "alter table t add column pk2 int"
|
||||
dolt sql -q "alter table t drop primary key"
|
||||
@@ -1387,7 +1387,7 @@ create table t(pk int, val int);
|
||||
insert into t values (1,1);
|
||||
SQL
|
||||
dolt add .
|
||||
dolt commit -am "creating table"
|
||||
dolt add . && dolt commit -m "creating table"
|
||||
|
||||
dolt sql -q "alter table t add primary key (pk)"
|
||||
|
||||
@@ -1404,7 +1404,7 @@ SQL
|
||||
[[ "$output" =~ "Primary key sets differ between revisions for table 't', skipping data diff" ]] || false
|
||||
|
||||
|
||||
dolt commit -am 'added primary key'
|
||||
dolt add . && dolt commit -m 'added primary key'
|
||||
|
||||
dolt sql -q "alter table t drop primary key"
|
||||
|
||||
@@ -1462,10 +1462,10 @@ SQL
|
||||
done
|
||||
|
||||
dolt sql -q "INSERT INTO t values $VALUES"
|
||||
dolt commit -am "Add the initial rows"
|
||||
dolt add . && dolt commit -m "Add the initial rows"
|
||||
|
||||
dolt sql -q "UPDATE t set val = val + 1 WHERE pk < 10000"
|
||||
dolt commit -am "make a bulk update creating a large diff"
|
||||
dolt add . && dolt commit -m "make a bulk update creating a large diff"
|
||||
|
||||
run dolt diff HEAD~1
|
||||
[ "${#lines[@]}" -eq 2007 ] # 2000 diffs + 6 for top rows before data + 1 for bottom row of table
|
||||
@@ -1609,7 +1609,7 @@ CREATE TABLE t2 (pk1a int, pk1b int, col1 int, PRIMARY KEY (pk1a, pk1b));
|
||||
INSERT INTO t2 VALUES (1, 1, 1);
|
||||
call dolt_add('.');
|
||||
SQL
|
||||
dolt commit -am "initial"
|
||||
dolt add . && dolt commit -m "initial"
|
||||
|
||||
dolt sql <<SQL
|
||||
ALTER TABLE t1 RENAME COLUMN pk to pk2;
|
||||
@@ -1619,7 +1619,7 @@ ALTER TABLE t2 RENAME COLUMN pk1b to pk2b;
|
||||
UPDATE t2 set col1 = 100;
|
||||
call dolt_add('.');
|
||||
SQL
|
||||
dolt commit -am 'rename primary key'
|
||||
dolt add . && dolt commit -m 'rename primary key'
|
||||
|
||||
run dolt diff HEAD~1 HEAD
|
||||
[ $status -eq 0 ]
|
||||
@@ -1653,7 +1653,7 @@ EOF
|
||||
dolt sql -q "Insert into t values (1), (2), (3);"
|
||||
dolt sql -q "alter table t add column col1 int;"
|
||||
dolt add .
|
||||
dolt commit -am "setup"
|
||||
dolt add . && dolt commit -m "setup"
|
||||
|
||||
# Turn a short tuple into a nominal one
|
||||
dolt sql -q "UPDATE t set col1 = 1 where pk = 1;"
|
||||
@@ -1722,7 +1722,7 @@ SQL
|
||||
fi
|
||||
|
||||
dolt add .
|
||||
dolt commit -am "commit 1"
|
||||
dolt add . && dolt commit -m "commit 1"
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE mytable(pk BIGINT PRIMARY KEY AUTO_INCREMENT, v1 BIGINT);
|
||||
CREATE TRIGGER trigger1 BEFORE INSERT ON mytable FOR EACH ROW SET new.v1 = -new.v1;
|
||||
@@ -2015,7 +2015,7 @@ insert into test values (2,'small');
|
||||
insert into test values (3,'medium');
|
||||
SQL
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql <<SQL
|
||||
insert into test values (4,'large');
|
||||
@@ -2057,7 +2057,7 @@ insert into test values (2,'small');
|
||||
insert into test values (3,'medium');
|
||||
SQL
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql <<SQL
|
||||
alter table test add column c1 int;
|
||||
@@ -2134,7 +2134,7 @@ create table test (pk int primary key auto_increment);
|
||||
insert into test values (1);
|
||||
SQL
|
||||
dolt add .
|
||||
dolt commit -am "First commit"
|
||||
dolt add . && dolt commit -m "First commit"
|
||||
|
||||
dolt sql <<SQL
|
||||
insert into test values (2);
|
||||
@@ -2245,3 +2245,155 @@ EOF
|
||||
[[ "$output" =~ "dolt_tests" ]] || false
|
||||
[[ "$output" =~ "updated description" ]] || false
|
||||
}
|
||||
|
||||
@test "diff: --filter option filters by diff type" {
|
||||
dolt sql -q "create table t(pk int primary key, val int)"
|
||||
dolt add .
|
||||
dolt commit -m "create table"
|
||||
|
||||
# Test filter with table addition
|
||||
run dolt diff HEAD~1 --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output =~ 'diff --dolt a/t b/t' ]] || false
|
||||
[[ $output =~ 'added table' ]] || false
|
||||
|
||||
# Test filter with row inserts
|
||||
dolt sql -q "INSERT INTO t VALUES (1, 10)"
|
||||
dolt sql -q "INSERT INTO t VALUES (2, 10)"
|
||||
dolt sql -q "INSERT INTO t VALUES (3, 10)"
|
||||
dolt add .
|
||||
dolt commit -m "add initial rows"
|
||||
|
||||
run dolt diff HEAD~1 --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'INSERT INTO `t` (`pk`,`val`) VALUES (1,10);' ]
|
||||
[ "${lines[1]}" = 'INSERT INTO `t` (`pk`,`val`) VALUES (2,10);' ]
|
||||
[ "${lines[2]}" = 'INSERT INTO `t` (`pk`,`val`) VALUES (3,10);' ]
|
||||
|
||||
# Test filter with row updates
|
||||
dolt sql -q "UPDATE t SET val=12 where pk=1"
|
||||
dolt add .
|
||||
dolt commit -m "update row"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=modified
|
||||
[ "${lines[0]}" = 'UPDATE `t` SET `val`=12 WHERE (`pk`=1);' ]
|
||||
|
||||
# Test filter with row deletes
|
||||
dolt sql -q "DELETE from t where pk=1"
|
||||
|
||||
dolt add . && dolt commit -m "delete row"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'DELETE FROM `t` WHERE (`pk`=1);' ]
|
||||
|
||||
# Test filter with schema changes - add column
|
||||
dolt sql -q "ALTER TABLE t ADD val2 int"
|
||||
|
||||
dolt add . && dolt commit -m "add a col"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'ALTER TABLE `t` ADD `val2` INT;' ]
|
||||
|
||||
# Test filter with schema changes - modify column type
|
||||
dolt sql -q "ALTER TABLE t MODIFY COLUMN val2 varchar(255)"
|
||||
|
||||
dolt add . && dolt commit -m "change datatype of column"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'ALTER TABLE `t` DROP `val2`;' ]
|
||||
[ "${lines[1]}" = 'ALTER TABLE `t` ADD `val2` VARCHAR(255);' ]
|
||||
|
||||
# Test filter with schema changes - rename column
|
||||
dolt sql -q "ALTER TABLE t RENAME COLUMN val2 TO val3"
|
||||
|
||||
dolt add . && dolt commit -m "rename column"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'ALTER TABLE `t` RENAME COLUMN `val2` TO `val3`;' ]
|
||||
|
||||
# Test filter with schema changes - drop column
|
||||
dolt sql -q "ALTER TABLE t DROP COLUMN val3"
|
||||
|
||||
dolt add . && dolt commit -m "drop column"
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=added
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=removed
|
||||
[ $status -eq 0 ]
|
||||
[[ $output = '' ]] || false
|
||||
|
||||
run dolt diff HEAD~1 -r sql --filter=modified
|
||||
[ $status -eq 0 ]
|
||||
[ "${lines[0]}" = 'ALTER TABLE `t` DROP `val3`;' ]
|
||||
}
|
||||
|
||||
@test "diff: --filter with invalid value returns error" {
|
||||
dolt sql -q "create table t(pk int primary key)"
|
||||
dolt add . && dolt commit -m "create table"
|
||||
|
||||
run dolt diff HEAD~1 --filter=invalid
|
||||
[ $status -eq 1 ]
|
||||
[[ $output =~ "invalid filter" ]] || false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user