Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 27 additions & 31 deletions test/unit/configs/test_config_naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,30 @@
import pytest


class TestConfigNaming:
"""Test Config parameter names with underscores and dashes."""

def test_flow_completes(self, config_naming_run):
"""Test that the flow completes successfully."""
assert config_naming_run.successful
assert config_naming_run.finished

def test_config_with_underscore(self, config_naming_run):
"""Test Config with underscore in name."""
end_task = config_naming_run["end"].task

assert end_task["underscore_test"].data == "underscore"
assert end_task["underscore_value"].data == 42
assert end_task["underscore_dict"].data == {"test": "underscore", "value": 42}

def test_config_with_dash(self, config_naming_run):
"""Test Config with dash in name."""
end_task = config_naming_run["end"].task

assert end_task["dash_test"].data == "dash"
assert end_task["dash_value"].data == 99
assert end_task["dash_dict"].data == {"test": "dash", "value": 99}

def test_config_with_mixed_naming(self, config_naming_run):
"""Test Config with both underscores and dashes in name."""
end_task = config_naming_run["end"].task

assert end_task["mixed_test"].data == "mixed"
assert end_task["mixed_value"].data == 123
assert end_task["mixed_dict"].data == {"test": "mixed", "value": 123}
def test_flow_completes(config_naming_run):
"""Test that the configuration parsing flow completes successfully."""
assert config_naming_run.successful
assert config_naming_run.finished


@pytest.mark.parametrize(
"prefix, expected_text, expected_value",
[
("underscore", "underscore", 42),
("dash", "dash", 99),
("mixed", "mixed", 123),
],
ids=["underscore_naming", "dash_naming", "mixed_naming"],
)
def test_config_parameter_naming_formats(
config_naming_run, prefix, expected_text, expected_value
):
"""Test that configuration parameters parse correctly across different naming conventions."""
end_task = config_naming_run["end"].task

assert end_task[f"{prefix}_test"].data == expected_text
assert end_task[f"{prefix}_value"].data == expected_value
assert end_task[f"{prefix}_dict"].data == {
"test": expected_text,
"value": expected_value,
}
87 changes: 40 additions & 47 deletions test/unit/configs/test_config_plain.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,43 @@
import pytest


class TestConfigPlain:
"""Test Config with plain=True option."""

def test_flow_completes(self, config_plain_run):
"""Test that the flow completes successfully."""
assert config_plain_run.successful
assert config_plain_run.finished

def test_plain_string_without_parser(self, config_plain_run):
"""Test plain Config without parser returns raw string."""
end_task = config_plain_run["end"].task

# Verify it's a string
assert end_task["plain_str_type"].data == "str"

# Verify the value is the raw string (not parsed JSON)
assert end_task["plain_str_value"].data == '{"raw": "string", "number": 123}'

def test_plain_list_with_parser(self, config_plain_run):
"""Test plain Config with parser returning list (non-dict)."""
end_task = config_plain_run["end"].task

# Verify it's a list
assert end_task["plain_list_type"].data == "list"

# Verify the list contents
assert end_task["plain_list_value"].data == [
"apple",
"banana",
"cherry",
"date",
]
assert end_task["plain_list_length"].data == 4
assert end_task["plain_list_first"].data == "apple"

def test_plain_tuple_with_parser(self, config_plain_run):
"""Test plain Config with parser returning tuple (non-dict)."""
end_task = config_plain_run["end"].task

# Verify it's a tuple type
assert end_task["plain_tuple_type"].data == "tuple"

# Verify tuple contents
assert end_task["plain_tuple_value"].data == ("test_tuple", 42, True)
assert end_task["tuple_name"].data == "test_tuple"
assert end_task["tuple_count"].data == 42
assert end_task["tuple_enabled"].data == True
def test_flow_completes(config_plain_run):
"""Test that the configuration plain parsing flow completes successfully."""
assert config_plain_run.successful
assert config_plain_run.finished


@pytest.mark.parametrize(
"key_prefix, expected_type, expected_value",
[
("plain_str", "str", '{"raw": "string", "number": 123}'),
("plain_list", "list", ["apple", "banana", "cherry", "date"]),
("plain_tuple", "tuple", ("test_tuple", 42, True)),
],
ids=["raw_string", "parsed_list", "parsed_tuple"],
)
def test_plain_config_types_and_values(
config_plain_run, key_prefix, expected_type, expected_value
):
"""Test that plain Config fields yield the expected type and exact raw or parsed values."""
end_task = config_plain_run["end"].task

assert end_task[f"{key_prefix}_type"].data == expected_type
assert end_task[f"{key_prefix}_value"].data == expected_value


def test_plain_list_properties(config_plain_run):
"""Test detailed extraction and length properties of a plain parsed list."""
end_task = config_plain_run["end"].task

assert end_task["plain_list_length"].data == 4
assert end_task["plain_list_first"].data == "apple"


def test_plain_tuple_properties(config_plain_run):
"""Test detailed extraction and inner structures of a plain parsed tuple."""
end_task = config_plain_run["end"].task

assert end_task["tuple_name"].data == "test_tuple"
assert end_task["tuple_count"].data == 42
assert end_task["tuple_enabled"].data is True
37 changes: 26 additions & 11 deletions test/unit/graph_inference/test_card_dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""

import json
import pytest

from metaflow.plugins.cards.card_modules.basic import (
DefaultCardJSON,
Expand All @@ -20,6 +21,7 @@


def _find_components_by_type(node, component_type):
"""Recursively search for components of a specific type in a card JSON structure."""
if isinstance(node, dict):
if node.get("type") == component_type:
yield node
Expand All @@ -31,12 +33,14 @@ def _find_components_by_type(node, component_type):


# ---------------------------------------------------------------------------
# transform_flow_graph: shape-detection unit tests
# Fixtures
# ---------------------------------------------------------------------------


def test_transform_flow_graph_supports_explicit_endpoints():
graph = {
@pytest.fixture
def explicit_endpoints_graph():
"""Provides a fresh graph definition with custom explicit start/end steps."""
return {
"start_step": "begin",
"end_step": "finish",
"steps": {
Expand All @@ -46,7 +50,23 @@ def test_transform_flow_graph_supports_explicit_endpoints():
},
}

transformed = transform_flow_graph(graph)

@pytest.fixture
def legacy_graph():
"""Provides a fresh legacy graph definition relying on hardcoded keys."""
return {
"start": {"type": "start", "next": ["end"], "doc": ""},
"end": {"type": "end", "next": [], "doc": ""},
}


# ---------------------------------------------------------------------------
# transform_flow_graph: shape-detection unit tests
# ---------------------------------------------------------------------------


def test_transform_flow_graph_supports_explicit_endpoints(explicit_endpoints_graph):
transformed = transform_flow_graph(explicit_endpoints_graph)

assert transformed["start_step"] == "begin"
assert transformed["end_step"] == "finish"
Expand All @@ -56,13 +76,8 @@ def test_transform_flow_graph_supports_explicit_endpoints():
assert transformed["steps"]["finish"]["type"] == "end"


def test_transform_flow_graph_keeps_legacy_start_end_detection():
graph = {
"start": {"type": "start", "next": ["end"], "doc": ""},
"end": {"type": "end", "next": [], "doc": ""},
}

transformed = transform_flow_graph(graph)
def test_transform_flow_graph_keeps_legacy_start_end_detection(legacy_graph):
transformed = transform_flow_graph(legacy_graph)

assert transformed["start_step"] == "start"
assert transformed["end_step"] == "end"
Expand Down
Loading
Loading