import pytest
from fasthtml.components import *
from components.debugger.components.JsonViewer import JsonViewer, DictNode, ListNode, ValueNode
from helpers import matches, span_icon, search_elements_by_name
JSON_VIEWER_INSTANCE_ID = "json_viewer"
ML_20 = "margin-left: 20px;"
CLS_PREFIX = "mmt-jsonviewer"
USER_ID = "user_id"
dn = DictNode
ln = ListNode
n = ValueNode
@pytest.fixture()
def json_viewer(session):
return JsonViewer(session, JSON_VIEWER_INSTANCE_ID, None, USER_ID, {})
def jv_id(x):
return f"{JSON_VIEWER_INSTANCE_ID}-{x}"
@pytest.mark.parametrize("data, expected_node", [
({}, dn({}, jv_id(0), 0, {})),
([], ln([], jv_id(0), 0, [])),
(1, n(1)),
("value", n("value")),
(True, n(True)),
(None, n(None)),
([1, 2, 3], ln([1, 2, 3], jv_id(0), 0, [n(1), n(2), n(3)])),
({"a": 1, "b": 2}, dn({"a": 1, "b": 2}, jv_id(0), 0, {"a": n(1), "b": n(2)})),
({"a": [1, 2]}, dn({"a": [1, 2]}, jv_id(0), 0, {"a": ln([1, 2], jv_id(1), 1, [n(1), n(2)])})),
([{"a": [1, 2]}],
ln([{"a": [1, 2]}], jv_id(0), 0, [dn({"a": [1, 2]}, jv_id(1), 1, {"a": ln([1, 2], jv_id(2), 2, [n(1), n(2)])})]))
])
def test_i_can_create_node(data, expected_node):
json_viewer_ = JsonViewer(None, JSON_VIEWER_INSTANCE_ID, None, USER_ID, data)
assert json_viewer_.node == expected_node
def test_i_can_render(json_viewer):
actual = json_viewer.__ft__()
expected = Div(
Div(Div(id=f"{jv_id('0')}"), id=f"{jv_id('root')}"), # root debug
cls=f"{CLS_PREFIX}",
id=JSON_VIEWER_INSTANCE_ID)
assert matches(actual, expected)
@pytest.mark.parametrize("value, expected_inner", [
("hello world", Span('"hello world"', cls=f"{CLS_PREFIX}-string")),
(1, Span("1", cls=f"{CLS_PREFIX}-number")),
(True, Span("true", cls=f"{CLS_PREFIX}-bool")),
(False, Span("false", cls=f"{CLS_PREFIX}-bool")),
(None, Span("null", cls=f"{CLS_PREFIX}-null")),
])
def test_i_can_render_simple_value(session, value, expected_inner):
jsonv = JsonViewer(session, JSON_VIEWER_INSTANCE_ID, None, USER_ID, value)
actual = jsonv.__ft__()
to_compare = search_elements_by_name(actual, "div", attrs={"id": f"{jv_id("root")}"})[0]
expected = Div(
Div(
None, # no folding
None, # # 'key :' is missing for the first node
expected_inner,
style=ML_20),
id=f"{jv_id("root")}")
assert matches(to_compare, expected)
def test_i_can_render_expanded_list_node(session):
value = [1, "hello", True]
jsonv = JsonViewer(session, JSON_VIEWER_INSTANCE_ID, None, USER_ID, value)
actual = jsonv.__ft__()
to_compare = search_elements_by_name(actual, "div", attrs={"id": f"{jv_id("root")}"})[0]
to_compare = to_compare.children[0] # I want to compare what is inside the div
expected_inner = Span("[",
Div(None, Span("0 : "), Span('1'), style=ML_20),
Div(None, Span("1 : "), Span('"hello"'), style=ML_20),
Div(None, Span("2 : "), Span('true'), style=ML_20),
Div("]")),
expected = Div(
span_icon("expanded"),
None, # 'key :' is missing for the first node
expected_inner,
style=ML_20)
assert matches(to_compare, expected)
def test_i_can_render_expanded_dict_node(session):
value = {"a": 1, "b": "hello", "c": True}
jsonv = JsonViewer(session, JSON_VIEWER_INSTANCE_ID, None, USER_ID, value)
actual = jsonv.__ft__()
to_compare = search_elements_by_name(actual, "div", attrs={"id": f"{jv_id("root")}"})[0]
to_compare = to_compare.children[0] # I want to compare what is inside the div
expected_inner = Span("{",
Div(None, Span("a : "), Span('1'), style=ML_20),
Div(None, Span("b : "), Span('"hello"'), style=ML_20),
Div(None, Span("c : "), Span('true'), style=ML_20),
Div("}"))
expected = Div(
span_icon("expanded"),
None, # 'key :' is missing for the first node
expected_inner,
style=ML_20)
assert matches(to_compare, expected)
def test_i_can_render_expanded_list_of_dict_node(session):
value = [{"a": 1, "b": "hello"}]
jsonv = JsonViewer(session, JSON_VIEWER_INSTANCE_ID, None, USER_ID, value)
actual = jsonv.__ft__()
to_compare = search_elements_by_name(actual, "div", attrs={"id": f"{jv_id("root")}"})[0]
to_compare = to_compare.children[0] # I want to compare what is inside the div
expected_inner = Span("[",
Div(span_icon("expanded"),
Span("0 : "),
Span("{",
Div(None, Span("a : "), Span('1'), style=ML_20),
Div(None, Span("b : "), Span('"hello"'), style=ML_20),
Div("}")),
id=f"{jv_id(1)}"),
Div("]"))
expected = Div(
span_icon("expanded"),
None, # 'key :' is missing for the first node
expected_inner,
style=ML_20)
assert matches(to_compare, expected)
@pytest.mark.parametrize("input_value, expected_output", [
('Hello World', '"Hello World"'), # No quotes in input
('Hello "World"', "'Hello \"World\"'"), # Contains double quotes
("Hello 'World'", '"Hello \'World\'"'), # Contains single quotes
('Hello "World" and \'Universe\'', '"Hello \\"World\\" and \'Universe\'"'), # both single and double quotes
('', '""'), # Empty string
])
def test_add_quotes(input_value, expected_output):
result = JsonViewer.add_quotes(input_value)
assert result == expected_output