Skip to content

Throw string literal value errors #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 24, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions gt_extras/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ def gt_highlight_cols(
gte.gt_highlight_cols(gt, columns="hp")
```
"""
# Throw if `font_weight` is not one of the allowed values
if isinstance(font_weight, str):
if font_weight not in ["normal", "bold", "bolder", "lighter"]:
raise ValueError("Font_weight must be one of 'normal', 'bold', 'bolder', or 'lighter', or an integer")
elif not isinstance(font_weight, (int, float)):
raise TypeError("Font_weight must be an int, float, or str")

if alpha:
fill = _html_color(colors=[fill], alpha=alpha)[0]

Expand Down
2 changes: 1 addition & 1 deletion gt_extras/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def with_tooltip(
An HTML string containing the formatted tooltip element.
"""

# Throw if `text_decoration_style` is not one of the three allowed values
# Throw if `text_decoration_style` is not one of the allowed values
if text_decoration_style not in [None, "solid", "dotted"]:
raise ValueError("Text_decoration_style must be one of `None`, 'solid', or 'dotted'")

Expand Down
4 changes: 4 additions & 0 deletions gt_extras/icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ def fa_icon_repeat(
--------
See `icon_svg()` in the `faicons` package for further implementation details.
"""
# Throw if `a11y` is not one of the allowed values
if a11y not in [None, "deco", "sem"]:
raise ValueError("A11y must be one of `None`, 'deco', or 'sem'")

if repeats < 0:
raise ValueError("repeats must be >= 0")

Expand Down
8 changes: 6 additions & 2 deletions gt_extras/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ def gt_plt_bar(
"""
# A version with svg.py

# Throw if `scale_type` is not one of the allowed values
if scale_type not in [None, "percent", "number"]:
raise ValueError("Scale_type must be one of `None`, 'percent', or 'number'")

if bar_height > height:
bar_height = height
warnings.warn(
Expand Down Expand Up @@ -186,7 +190,7 @@ def _make_bar_html(
if stroke_color is None:
stroke_color = "#FFFFFF00"

def make_bar(scaled_val: int, original_val: int) -> str:
def _make_bar(scaled_val: int, original_val: int) -> str:
return _make_bar_html(
scaled_val=scaled_val,
original_val=original_val,
Expand Down Expand Up @@ -215,7 +219,7 @@ def make_bar(scaled_val: int, original_val: int) -> str:
# Apply the scaled value for each row, so the bar is proportional
for i, scaled_val in enumerate(scaled_vals):
res = res.fmt(
lambda original_val, scaled_val=scaled_val: make_bar(
lambda original_val, scaled_val=scaled_val: _make_bar(
original_val=original_val,
scaled_val=scaled_val,
),
Expand Down
14 changes: 14 additions & 0 deletions gt_extras/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ def test_gt_highlight_cols_alpha(mini_gt):
assert "#80bcd833" in html


def test_gt_highlight_cols_font_weight_invalid_string(mini_gt):
with pytest.raises(
ValueError,
match="Font_weight must be one of 'normal', 'bold', 'bolder', or 'lighter', or an integer",
):
gt_highlight_cols(mini_gt, font_weight="invalid")


@pytest.mark.parametrize("invalid_weight", [(1.5, 5), [], {}, None])
def test_gt_highlight_cols_font_weight_invalid_type(mini_gt, invalid_weight):
with pytest.raises(TypeError, match="Font_weight must be an int, float, or str"):
gt_highlight_cols(mini_gt, font_weight=invalid_weight)


def test_gt_hulk_col_numeric_snap(snapshot, mini_gt):
res = gt_hulk_col_numeric(mini_gt)
assert_rendered_body(snapshot, gt=res)
Expand Down
68 changes: 43 additions & 25 deletions gt_extras/tests/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,48 @@
from great_tables import GT
from gt_extras.html import gt_hyperlink, with_tooltip


def test_gt_hyperlink_basic():
result = gt_hyperlink("Google", "https://google.com")
expected = '<a href="https://google.com" target="_blank">Google</a>'
assert result == expected


def test_gt_hyperlink_new_tab_false():
result = gt_hyperlink("Google", "https://google.com", new_tab=False)
expected = '<a href="https://google.com" target="_self">Google</a>'
assert result == expected


def test_gt_hyperlink_new_tab_true():
result = gt_hyperlink("GitHub", "https://github.com", new_tab=True)
expected = '<a href="https://github.com" target="_blank">GitHub</a>'
assert result == expected


def test_gt_hyperlink_empty_text():
result = gt_hyperlink("", "https://example.com")
expected = '<a href="https://example.com" target="_blank"></a>'
assert result == expected


def test_gt_hyperlink_in_table():
df = pd.DataFrame({
"Name": ["Google", "GitHub"],
"Link": [
gt_hyperlink("Visit Google", "https://google.com"),
gt_hyperlink("View GitHub", "https://github.com", new_tab=False)
]
})

df = pd.DataFrame(
{
"Name": ["Google", "GitHub"],
"Link": [
gt_hyperlink("Visit Google", "https://google.com"),
gt_hyperlink("View GitHub", "https://github.com", new_tab=False),
],
}
)

gt_table = GT(df)
html_output = gt_table.as_raw_html()

assert '<a href="https://google.com" target="_blank">Visit Google</a>' in html_output

assert (
'<a href="https://google.com" target="_blank">Visit Google</a>' in html_output
)
assert "https://github.com" in html_output
assert 'target="_blank"' in html_output
assert 'target="_self"' in html_output
Expand All @@ -46,40 +55,49 @@ def test_with_tooltip_basic():
expected = '<abbr style="cursor: help; text-decoration: underline; text-decoration-style: dotted; color: blue; " title="Number One">1</abbr>'
assert result == expected


def test_with_tooltip_underline_style():
result = with_tooltip("1", "Number One", text_decoration_style="solid")
expected = '<abbr style="cursor: help; text-decoration: underline; text-decoration-style: solid; color: blue; " title="Number One">1</abbr>'
assert result == expected


def test_with_tooltip_underline_fail():
with pytest.raises(ValueError):
with_tooltip("1", "Number One", text_decoration_style="underline")


def test_with_tooltip_no_decoration():
result = with_tooltip("1", "Number One", text_decoration_style=None)
expected = '<abbr style="cursor: help; text-decoration: none; color: blue; " title="Number One">1</abbr>'
assert result == expected


def test_with_tooltip_no_color():
result = with_tooltip("1", "Number One", color=None)
expected = '<abbr style="cursor: help; text-decoration: underline; text-decoration-style: dotted; " title="Number One">1</abbr>'
assert result == expected

def test_with_tooltip_in_table():
df = pd.DataFrame({
"Number": ["1", "2"],
"Description": [
with_tooltip("1", "Number One"),
with_tooltip("2", "Number Two", text_decoration_style="solid", color="red")
]
})


def test_with_tooltip_in_table():
df = pd.DataFrame(
{
"Number": ["1", "2"],
"Description": [
with_tooltip("1", "Number One"),
with_tooltip(
"2", "Number Two", text_decoration_style="solid", color="red"
),
],
}
)

html_output = GT(df).as_raw_html()

assert 'title="Number One"' in html_output
assert 'title="Number Two"' in html_output
assert 'cursor: help' in html_output
assert 'text-decoration-style: dotted' in html_output
assert 'text-decoration-style: solid' in html_output
assert 'color: blue' in html_output
assert 'color: red' in html_output
assert "cursor: help" in html_output
assert "text-decoration-style: dotted" in html_output
assert "text-decoration-style: solid" in html_output
assert "color: blue" in html_output
assert "color: red" in html_output
7 changes: 7 additions & 0 deletions gt_extras/tests/test_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,10 @@ def test_gt_fa_rating_multiple_columns():

assert html.count("<svg") == 20
assert "out of 5" in html


def test_fa_icon_repeat_a11y_invalid_string():
with pytest.raises(
ValueError, match="A11y must be one of `None`, 'deco', or 'sem'"
):
fa_icon_repeat(a11y="invalid")
7 changes: 7 additions & 0 deletions gt_extras/tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ def test_gt_plt_bar_no_stroke_color(mini_gt):
assert html.count("#FFFFFF00") == 3


def test_gt_plt_bar_scale_type_invalid_string(mini_gt):
with pytest.raises(
ValueError, match="Scale_type must be one of `None`, 'percent', or 'number'"
):
gt_plt_bar(mini_gt, scale_type="invalid")


def test_gt_plt_bar_type_error(mini_gt):
with pytest.raises(TypeError, match="Invalid column type provided"):
gt_plt_bar(gt=mini_gt, columns=["char"]).as_raw_html()
Expand Down
16 changes: 14 additions & 2 deletions gt_extras/tests/test_themes.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,59 +22,71 @@ def test_theme_538_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_538(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_espn_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_espn(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_nytimes_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_nytimes(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_guardian_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_guardian(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_excel_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_excel(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_excel_color(mini_gt):
themed_gt = gt_theme_excel(gt=mini_gt, color="lightblue")
html = themed_gt.as_raw_html()
assert "lightblue" in html


def test_theme_dot_matrix_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_dot_matrix(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_dot_matrix_color(mini_gt):
themed_gt = gt_theme_dot_matrix(gt=mini_gt, color="lightblue")
html = themed_gt.as_raw_html()
assert "lightblue" in html


def test_theme_dark_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_dark(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_pff_fonts_snap(snapshot, mini_gt):
themed_gt = gt_theme_pff(gt=mini_gt)
assert_rendered_global_imports(snapshot, themed_gt)


def test_theme_pff_dividers(mini_gt):
themed_gt = gt_theme_pff(gt=mini_gt, divider="num")
html = themed_gt.as_raw_html()
print(html)
assert "border-left: 2px solid lightgrey" in html


def test_theme_pff_spanner(mini_gt):
gt_with_spanner = mini_gt.tab_spanner("Spanner Label", columns=["num", "char"])
themed_gt = gt_theme_pff(gt=gt_with_spanner, spanners=["Spanner Label"])
html = themed_gt.as_raw_html()
assert "Spanner Label" in html
assert "Spanner Label" in html
# This assertion ensures the blank spanner is created
assert '<span class="gt_column_spanner"> </span>' in html


def test_theme_pff_rank_col(mini_gt):
themed_gt = gt_theme_pff(gt=mini_gt, rank_col="num")
html = themed_gt.as_raw_html()
assert "#e4e8ec" in html
assert "#e4e8ec" in html
Loading