1111from unittest .mock import MagicMock , patch
1212
1313from schema_scribe .workflows .db_workflow import DbWorkflow
14- from schema_scribe .core .interfaces import BaseConnector , BaseLLMClient , BaseWriter
14+ from schema_scribe .core .interfaces import (
15+ BaseConnector ,
16+ BaseLLMClient ,
17+ BaseWriter ,
18+ )
1519
1620
1721@pytest .fixture
@@ -27,33 +31,97 @@ def mock_db_connector(sqlite_db: str):
2731 {"name" : "orders" , "comment" : None },
2832 ]
2933 mock_connector .get_views .return_value = [
30- {"name" : "user_orders" , "definition" : "SELECT * FROM users JOIN orders ON users.id = orders.user_id" }
34+ {
35+ "name" : "user_orders" ,
36+ "definition" : "SELECT * FROM users JOIN orders ON users.id = orders.user_id" ,
37+ }
3138 ]
3239 mock_connector .get_columns .side_effect = [
3340 # users table columns
3441 [
35- {"name" : "id" , "type" : "INTEGER" , "is_nullable" : False , "is_pk" : True , "comment" : None },
36- {"name" : "email" , "type" : "TEXT" , "is_nullable" : False , "is_pk" : False , "comment" : None },
42+ {
43+ "name" : "id" ,
44+ "type" : "INTEGER" ,
45+ "is_nullable" : False ,
46+ "is_pk" : True ,
47+ "comment" : None ,
48+ },
49+ {
50+ "name" : "email" ,
51+ "type" : "TEXT" ,
52+ "is_nullable" : False ,
53+ "is_pk" : False ,
54+ "comment" : None ,
55+ },
3756 ],
3857 # products table columns
3958 [
40- {"name" : "id" , "type" : "INTEGER" , "is_nullable" : False , "is_pk" : True , "comment" : None },
41- {"name" : "name" , "type" : "TEXT" , "is_nullable" : False , "is_pk" : False , "comment" : None },
42- {"name" : "price" , "type" : "REAL" , "is_nullable" : False , "is_pk" : False , "comment" : None },
59+ {
60+ "name" : "id" ,
61+ "type" : "INTEGER" ,
62+ "is_nullable" : False ,
63+ "is_pk" : True ,
64+ "comment" : None ,
65+ },
66+ {
67+ "name" : "name" ,
68+ "type" : "TEXT" ,
69+ "is_nullable" : False ,
70+ "is_pk" : False ,
71+ "comment" : None ,
72+ },
73+ {
74+ "name" : "price" ,
75+ "type" : "REAL" ,
76+ "is_nullable" : False ,
77+ "is_pk" : False ,
78+ "comment" : None ,
79+ },
4380 ],
4481 # orders table columns
4582 [
46- {"name" : "id" , "type" : "INTEGER" , "is_nullable" : False , "is_pk" : True , "comment" : None },
47- {"name" : "user_id" , "type" : "INTEGER" , "is_nullable" : False , "is_pk" : False , "comment" : None },
48- {"name" : "product_id" , "type" : "INTEGER" , "is_nullable" : False , "is_pk" : False , "comment" : None },
83+ {
84+ "name" : "id" ,
85+ "type" : "INTEGER" ,
86+ "is_nullable" : False ,
87+ "is_pk" : True ,
88+ "comment" : None ,
89+ },
90+ {
91+ "name" : "user_id" ,
92+ "type" : "INTEGER" ,
93+ "is_nullable" : False ,
94+ "is_pk" : False ,
95+ "comment" : None ,
96+ },
97+ {
98+ "name" : "product_id" ,
99+ "type" : "INTEGER" ,
100+ "is_nullable" : False ,
101+ "is_pk" : False ,
102+ "comment" : None ,
103+ },
49104 ],
50105 ]
51106 mock_connector .get_foreign_keys .return_value = [
52- {"source_table" : "orders" , "source_column" : "user_id" , "target_table" : "users" , "target_column" : "id" },
53- {"source_table" : "orders" , "source_column" : "product_id" , "target_table" : "products" , "target_column" : "id" },
107+ {
108+ "source_table" : "orders" ,
109+ "source_column" : "user_id" ,
110+ "target_table" : "users" ,
111+ "target_column" : "id" ,
112+ },
113+ {
114+ "source_table" : "orders" ,
115+ "source_column" : "product_id" ,
116+ "target_table" : "products" ,
117+ "target_column" : "id" ,
118+ },
54119 ]
55120 mock_connector .get_column_profile .return_value = {
56- "total_count" : 0 , "null_count" : 0 , "distinct_count" : 0 , "is_unique" : True
121+ "total_count" : 0 ,
122+ "null_count" : 0 ,
123+ "distinct_count" : 0 ,
124+ "is_unique" : True ,
57125 }
58126 mock_connector .close .return_value = None
59127 return mock_connector
@@ -66,7 +134,9 @@ def mock_llm_client():
66134 """
67135 mock_client = MagicMock (spec = BaseLLMClient )
68136 mock_client .llm_profile_name = "test_llm"
69- mock_client .get_description .return_value = "This is an AI-generated description."
137+ mock_client .get_description .return_value = (
138+ "This is an AI-generated description."
139+ )
70140 return mock_client
71141
72142
@@ -113,9 +183,11 @@ def test_db_workflow_end_to_end(
113183 # 1. Verify components were called
114184 mock_db_connector .get_tables .assert_called_once ()
115185 mock_db_connector .get_views .assert_called_once ()
116- assert mock_db_connector .get_columns .call_count == 3 # Only called for tables
186+ assert (
187+ mock_db_connector .get_columns .call_count == 3
188+ ) # Only called for tables
117189 mock_db_connector .get_foreign_keys .assert_called_once ()
118- mock_llm_client .get_description .assert_called () # Called for tables, views, columns
190+ mock_llm_client .get_description .assert_called () # Called for tables, views, columns
119191 mock_writer .write .assert_called_once ()
120192 mock_db_connector .close .assert_called_once ()
121193
@@ -129,7 +201,7 @@ def test_db_workflow_end_to_end(
129201
130202 assert captured_writer_params == {
131203 "db_profile_name" : "test_db" ,
132- "db_connector" : mock_db_connector , # Added mock_db_connector to expected params
204+ "db_connector" : mock_db_connector , # Added mock_db_connector to expected params
133205 "output_filename" : str (output_md_path ),
134206 }
135207
@@ -182,7 +254,11 @@ def test_db_workflow_end_to_end_with_profiling(
182254 for call in calls :
183255 prompt_text = call [0 ][0 ]
184256 # Make the search more flexible
185- if "Table: {'name': 'users', 'comment': None}" in prompt_text and "Column: id" in prompt_text and "Data Profile Context:" in prompt_text :
257+ if (
258+ "Table: {'name': 'users', 'comment': None}" in prompt_text
259+ and "Column: id" in prompt_text
260+ and "Data Profile Context:" in prompt_text
261+ ):
186262 users_id_prompt = prompt_text
187263 break
188264
0 commit comments