package capabilities import ( "encoding/json" "testing" "github.com/danfragoso/pizzasql-next/pkg/version" ) func TestCurrentDocumentIsVersionedAndMarshalable(t *testing.T) { doc := Current() if doc.SchemaVersion != SchemaVersion { t.Fatalf("schema version = %d, want %d", doc.SchemaVersion, SchemaVersion) } if doc.Engine != "pizzasql" || doc.EngineVersion != version.String() { t.Fatalf("engine identity = %q/%q", doc.Engine, doc.EngineVersion) } body, err := json.Marshal(doc) if err != nil { t.Fatalf("marshal: %v", err) } var round Document if err := json.Unmarshal(body, &round); err != nil { t.Fatalf("unmarshal: %v", err) } if round.Constraints.Unique.SQLState != "23505" { t.Fatalf("unique SQLSTATE = %q, want 23505", round.Constraints.Unique.SQLState) } if round.Transactions.SerializationCode != "40001" { t.Fatalf("serialization SQLSTATE = %q, want 40001", round.Transactions.SerializationCode) } if round.ErrorCodes["0A000"] != "feature_not_supported" { t.Fatalf("0A000 mapping = %q", round.ErrorCodes["0A000"]) } if !round.Notifications.Listen.Supported || !round.Notifications.Notify.Supported { t.Fatal("LISTEN/NOTIFY should be advertised as supported") } if round.Notifications.PayloadLimit != 8000 || round.Notifications.DurableReplay { t.Fatalf("unexpected notification limits: %+v", round.Notifications) } if !round.DDL.RenameColumnIndexes.Supported { t.Fatal("RENAME COLUMN must advertise index metadata rewriting") } } func TestJSONArrowOperatorsAreAdvertised(t *testing.T) { arrow := Current().JSON.ArrowOperators if !arrow.Supported { t.Fatal("-> and ->> should be advertised as supported") } if arrow.SQLState != "" { t.Fatalf("arrow operator SQLSTATE = %q, want none", arrow.SQLState) } if arrow.Status == "rejected" { t.Fatalf("arrow operator status = %q, want a supported status", arrow.Status) } } func TestAddColumnBackfillIsAdvertised(t *testing.T) { doc := Current() if !doc.DDL.AddColumnBackfill.Supported { t.Fatalf("add_column_backfill = %+v, want supported", doc.DDL.AddColumnBackfill) } if doc.DDL.AddColumnBackfill.Status != "rewrites_rows" { t.Fatalf("add_column_backfill status = %q, want rewrites_rows", doc.DDL.AddColumnBackfill.Status) } if doc.DDL.AddColumn.Status == "metadata_only" { t.Fatalf("add_column status = %q, but a DEFAULT rewrites rows", doc.DDL.AddColumn.Status) } } // The capability document must describe the current default semantics: constant // and whitelisted clock defaults are supported, the clock ones are evaluated on // write, and only the remaining non-constant forms are rejected. func TestNonConstantDefaultsAreAdvertisedAsEvaluatedAtWriteTime(t *testing.T) { defaults := Current().Constraints.DefaultValues if !defaults.Supported { t.Fatalf("default_values = %+v, want supported", defaults) } if defaults.Status != "evaluated_at_write_time" { t.Fatalf("default_values status = %q, want evaluated_at_write_time", defaults.Status) } if defaults.SQLState != "0A000" { t.Fatalf("default_values SQLSTATE = %q, want 0A000 for the remaining rejected forms", defaults.SQLState) } }