feat(browser): auto-commit con 178 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
"""Tests para build_join_graph."""
|
||||
|
||||
from build_join_graph import build_join_graph
|
||||
|
||||
|
||||
def _star_fks():
|
||||
"""Esquema en estrella: orders apunta a customers y a products."""
|
||||
return [
|
||||
{
|
||||
"from_table": "orders",
|
||||
"from_col": "customer_id",
|
||||
"to_table": "customers",
|
||||
"to_col": "id",
|
||||
"inclusion": 1.0,
|
||||
"cardinality": "many-to-one",
|
||||
},
|
||||
{
|
||||
"from_table": "orders",
|
||||
"from_col": "product_id",
|
||||
"to_table": "products",
|
||||
"to_col": "id",
|
||||
"inclusion": 0.98,
|
||||
"cardinality": "many-to-one",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def test_star_schema_roles_and_hub():
|
||||
g = build_join_graph(_star_fks())
|
||||
nodes = {n["table"]: n for n in g["nodes"]}
|
||||
|
||||
assert nodes["orders"]["role"] == "fact"
|
||||
assert nodes["orders"]["out_degree"] == 2
|
||||
assert nodes["orders"]["in_degree"] == 0
|
||||
|
||||
assert nodes["customers"]["role"] == "dimension"
|
||||
assert nodes["customers"]["in_degree"] == 1
|
||||
assert nodes["customers"]["out_degree"] == 0
|
||||
|
||||
assert nodes["products"]["role"] == "dimension"
|
||||
|
||||
# orders es el hub (mayor out_degree).
|
||||
assert g["hubs"][0] == "orders"
|
||||
|
||||
|
||||
def test_two_edges_built():
|
||||
g = build_join_graph(_star_fks())
|
||||
assert len(g["edges"]) == 2
|
||||
pairs = {(e["from_table"], e["to_table"]) for e in g["edges"]}
|
||||
assert pairs == {("orders", "customers"), ("orders", "products")}
|
||||
|
||||
|
||||
def test_mermaid_contains_tables_and_arrows():
|
||||
g = build_join_graph(_star_fks())
|
||||
m = g["mermaid"]
|
||||
assert "orders" in m
|
||||
assert "customers" in m
|
||||
assert "products" in m
|
||||
assert "-->" in m
|
||||
# Etiqueta de columnas en la arista.
|
||||
assert "customer_id->id" in m
|
||||
|
||||
|
||||
def test_bridge_role():
|
||||
# order_items apunta a orders y products, y nadie le apunta -> fact en este
|
||||
# subgrafo. Para forzar bridge, hacemos que reciba tambien una FK.
|
||||
fks = [
|
||||
{"from_table": "shipments", "from_col": "order_item_id",
|
||||
"to_table": "order_items", "to_col": "id",
|
||||
"inclusion": 1.0, "cardinality": "many-to-one"},
|
||||
{"from_table": "order_items", "from_col": "product_id",
|
||||
"to_table": "products", "to_col": "id",
|
||||
"inclusion": 1.0, "cardinality": "many-to-one"},
|
||||
]
|
||||
g = build_join_graph(fks)
|
||||
nodes = {n["table"]: n for n in g["nodes"]}
|
||||
assert nodes["order_items"]["role"] == "bridge"
|
||||
assert nodes["order_items"]["in_degree"] == 1
|
||||
assert nodes["order_items"]["out_degree"] == 1
|
||||
|
||||
|
||||
def test_standalone_node_from_tables_list():
|
||||
g = build_join_graph(_star_fks(), tables=["orders", "customers", "products", "audit_log"])
|
||||
nodes = {n["table"]: n for n in g["nodes"]}
|
||||
assert "audit_log" in nodes
|
||||
assert nodes["audit_log"]["role"] == "standalone"
|
||||
assert nodes["audit_log"]["out_degree"] == 0
|
||||
assert nodes["audit_log"]["in_degree"] == 0
|
||||
# El nodo aislado aparece declarado en el mermaid.
|
||||
assert "audit_log" in g["mermaid"]
|
||||
|
||||
|
||||
def test_empty_list_does_not_crash():
|
||||
g = build_join_graph([])
|
||||
assert g["nodes"] == []
|
||||
assert g["edges"] == []
|
||||
assert g["hubs"] == []
|
||||
assert g["mermaid"].startswith("graph LR")
|
||||
|
||||
|
||||
def test_none_input_does_not_crash():
|
||||
g = build_join_graph(None)
|
||||
assert g["edges"] == []
|
||||
assert "graph LR" in g["mermaid"]
|
||||
|
||||
|
||||
def test_malformed_entries_skipped():
|
||||
fks = [
|
||||
{"from_table": "a", "from_col": "x", "to_table": "b", "to_col": "y"},
|
||||
{"from_table": "a"}, # falta to_table -> se ignora
|
||||
"not a dict", # no es dict -> se ignora
|
||||
{"to_table": "b"}, # falta from_table -> se ignora
|
||||
]
|
||||
g = build_join_graph(fks)
|
||||
assert len(g["edges"]) == 1
|
||||
assert g["edges"][0]["from_table"] == "a"
|
||||
|
||||
|
||||
def test_does_not_mutate_input():
|
||||
fks = _star_fks()
|
||||
snapshot = [dict(fk) for fk in fks]
|
||||
build_join_graph(fks)
|
||||
assert fks == snapshot
|
||||
Reference in New Issue
Block a user