11from __future__ import annotations
22
33import sqlite3
4+ from dataclasses import replace
45from types import SimpleNamespace
56
67import pytest
1213 InPlacePlanSubmission ,
1314 _apply_plan_on_connection ,
1415)
16+ from openstatspec .sql .profiles import (
17+ DOLT , SQLITE , TargetCapabilityExceededError ,
18+ )
1519from openstatspec .sql .wide import create_wide_dataset , validate_wide_dataset
1620
1721
@@ -102,6 +106,7 @@ def test_plan_applies_to_same_dataset_and_physical_table_without_copy(
102106 ),
103107 actor = "test-agent" ,
104108 database_profile = "sqlite" ,
109+ target_profile = inplace_transform .effective_profile (url )[0 ],
105110 allow_schema_change = True ,
106111 allow_delete_variable = True ,
107112 dolt_branch = None ,
@@ -318,6 +323,44 @@ def test_public_generic_plan_apply_accepts_object_and_mapping(
318323 )
319324
320325
326+ def test_generic_string_width_is_rejected_before_ddl (
327+ catalog , monkeypatch ,
328+ ) -> None :
329+ url , path , dataset_id , table_name = catalog
330+ monkeypatch .setattr (
331+ inplace_transform ,
332+ "effective_profile" ,
333+ lambda _url , ** _kwargs : (
334+ replace (SQLITE , max_text_value_bytes = 3 ),
335+ {"server_version" : "3.35.0" },
336+ ),
337+ )
338+ plan = openstatspec .TransformationPlan ((
339+ openstatspec .CreateVariableOperation ("note" , "string" , 4 ),
340+ ))
341+
342+ with pytest .raises (TargetCapabilityExceededError , match = "permits 3" ):
343+ openstatspec .apply_transformation_plan_in_place (
344+ database_url = url ,
345+ dataset_id = dataset_id ,
346+ plan = plan ,
347+ actor = "test-agent" ,
348+ )
349+
350+ connection = sqlite3 .connect (path )
351+ assert [
352+ row [1 ] for row in connection .execute (f'PRAGMA table_info("{ table_name } ")' )
353+ ] == ["__case_ordinal" , "score" ]
354+ assert connection .execute (
355+ "select source_name from variable where dataset_id = ?" ,
356+ (dataset_id ,),
357+ ).fetchall () == [("score" ,)]
358+ assert connection .execute (
359+ "select count(*) from transformation_apply"
360+ ).fetchone () == (0 ,)
361+ connection .close ()
362+
363+
321364def test_generic_plan_is_bound_to_live_schema_before_mutation (catalog ) -> None :
322365 url , path , dataset_id , table_name = catalog
323366 plan = openstatspec .TransformationPlan ((
@@ -481,7 +524,7 @@ def test_delete_is_rejected_when_drop_column_is_unavailable(
481524 inplace_transform ,
482525 "effective_profile" ,
483526 lambda _url , ** _kwargs : (
484- SimpleNamespace ( name = "sqlite" ) ,
527+ SQLITE ,
485528 {"server_version" : "3.34.0" },
486529 ),
487530 )
@@ -521,6 +564,7 @@ def test_nontransactional_ddl_profile_rejects_create_before_mutation(
521564 ),
522565 actor = "test-agent" ,
523566 database_profile = "mysql" ,
567+ target_profile = inplace_transform .effective_profile (url )[0 ],
524568 allow_schema_change = False ,
525569 allow_delete_variable = True ,
526570 dolt_branch = None ,
@@ -546,7 +590,7 @@ def test_public_apply_binds_expected_dolt_branch_and_head(
546590 monkeypatch .setattr (
547591 inplace_transform ,
548592 "effective_profile" ,
549- lambda _url , ** _kwargs : (SimpleNamespace ( name = "dolt" ) , {}),
593+ lambda _url , ** _kwargs : (DOLT , {}),
550594 )
551595 states = iter ([
552596 ("feature/recode" , "abc123" , 0 ),
@@ -577,7 +621,7 @@ def test_public_apply_rejects_dirty_dolt_working_set_before_mutation(
577621 monkeypatch .setattr (
578622 inplace_transform ,
579623 "effective_profile" ,
580- lambda _url , ** _kwargs : (SimpleNamespace ( name = "dolt" ) , {}),
624+ lambda _url , ** _kwargs : (DOLT , {}),
581625 )
582626 monkeypatch .setattr (
583627 inplace_transform ,
@@ -613,7 +657,7 @@ def test_public_apply_rejects_dolt_context_mismatch_before_mutation(
613657 monkeypatch .setattr (
614658 inplace_transform ,
615659 "effective_profile" ,
616- lambda _url , ** _kwargs : (SimpleNamespace ( name = "dolt" ) , {}),
660+ lambda _url , ** _kwargs : (DOLT , {}),
617661 )
618662 monkeypatch .setattr (
619663 inplace_transform , "_dolt_state" , lambda _connection : state
0 commit comments