Add pc.set_value (#835)
This commit is contained in:
parent
a9ee9f6d44
commit
1a254aca8e
@ -90,6 +90,11 @@ export const applyEvent = async (event, router, socket) => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.name == "_set_value") {
|
||||||
|
event.payload.ref.current.value = event.payload.value;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Send the event to the server.
|
// Send the event to the server.
|
||||||
event.token = getToken();
|
event.token = getToken();
|
||||||
event.router_data = (({ pathname, query }) => ({ pathname, query }))(router);
|
event.router_data = (({ pathname, query }) => ({ pathname, query }))(router);
|
||||||
|
@ -16,6 +16,7 @@ from .event import (
|
|||||||
EventChain,
|
EventChain,
|
||||||
console_log,
|
console_log,
|
||||||
redirect,
|
redirect,
|
||||||
|
set_value,
|
||||||
window_alert,
|
window_alert,
|
||||||
)
|
)
|
||||||
from .event import FileUpload as upload_files
|
from .event import FileUpload as upload_files
|
||||||
|
@ -181,7 +181,7 @@ class Component(Base, ABC):
|
|||||||
event_trigger: The event trigger to bind the chain to.
|
event_trigger: The event trigger to bind the chain to.
|
||||||
value: The value to create the event chain from.
|
value: The value to create the event chain from.
|
||||||
state_name: The state to be fully controlled.
|
state_name: The state to be fully controlled.
|
||||||
full_control: Whether full contorolled or not.
|
full_control: Whether full controlled or not.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The event chain.
|
The event chain.
|
||||||
@ -243,7 +243,7 @@ class Component(Base, ABC):
|
|||||||
events = [
|
events = [
|
||||||
EventSpec(
|
EventSpec(
|
||||||
handler=e.handler,
|
handler=e.handler,
|
||||||
local_args=(EVENT_ARG.name,),
|
local_args=(EVENT_ARG,),
|
||||||
args=get_handler_args(e, arg),
|
args=get_handler_args(e, arg),
|
||||||
)
|
)
|
||||||
for e in events
|
for e in events
|
||||||
@ -461,10 +461,18 @@ class Component(Base, ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _get_hooks(self) -> Optional[str]:
|
def _get_hooks(self) -> Optional[str]:
|
||||||
|
"""Get the React hooks for this component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The hooks for just this component.
|
||||||
|
"""
|
||||||
|
ref = self.get_ref()
|
||||||
|
if ref is not None:
|
||||||
|
return f"const {ref} = useRef(null);"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_hooks(self) -> Set[str]:
|
def get_hooks(self) -> Set[str]:
|
||||||
"""Get javascript code for react hooks.
|
"""Get the React hooks for this component and its children.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The code that should appear just before returning the rendered component.
|
The code that should appear just before returning the rendered component.
|
||||||
@ -483,6 +491,16 @@ class Component(Base, ABC):
|
|||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
|
def get_ref(self) -> Optional[str]:
|
||||||
|
"""Get the name of the ref for the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The ref name.
|
||||||
|
"""
|
||||||
|
if self.id is None:
|
||||||
|
return None
|
||||||
|
return format.format_ref(self.id)
|
||||||
|
|
||||||
def get_custom_components(
|
def get_custom_components(
|
||||||
self, seen: Optional[Set[str]] = None
|
self, seen: Optional[Set[str]] = None
|
||||||
) -> Set[CustomComponent]:
|
) -> Set[CustomComponent]:
|
||||||
|
@ -4,6 +4,7 @@ from typing import Dict
|
|||||||
|
|
||||||
from pynecone.components.component import EVENT_ARG
|
from pynecone.components.component import EVENT_ARG
|
||||||
from pynecone.components.libs.chakra import ChakraComponent
|
from pynecone.components.libs.chakra import ChakraComponent
|
||||||
|
from pynecone.utils import imports
|
||||||
from pynecone.var import Var
|
from pynecone.var import Var
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +49,12 @@ class Input(ChakraComponent):
|
|||||||
# "lg" | "md" | "sm" | "xs"
|
# "lg" | "md" | "sm" | "xs"
|
||||||
size: Var[str]
|
size: Var[str]
|
||||||
|
|
||||||
|
def _get_imports(self) -> imports.ImportDict:
|
||||||
|
return imports.merge_imports(
|
||||||
|
super()._get_imports(),
|
||||||
|
{"/utils/state": {"set_val"}},
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_controlled_triggers(cls) -> Dict[str, Var]:
|
def get_controlled_triggers(cls) -> Dict[str, Var]:
|
||||||
"""Get the event triggers that pass the component's value to the handler.
|
"""Get the event triggers that pass the component's value to the handler.
|
||||||
@ -63,6 +70,13 @@ class Input(ChakraComponent):
|
|||||||
"on_key_up": EVENT_ARG.key,
|
"on_key_up": EVENT_ARG.key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _render(self):
|
||||||
|
out = super()._render()
|
||||||
|
ref = self.get_ref()
|
||||||
|
if ref is not None:
|
||||||
|
out.add_props(ref=Var.create(ref, is_local=False))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
class InputGroup(ChakraComponent):
|
class InputGroup(ChakraComponent):
|
||||||
"""The InputGroup component is a component that is used to group a set of inputs."""
|
"""The InputGroup component is a component that is used to group a set of inputs."""
|
||||||
|
@ -73,7 +73,7 @@ class Tag(Base):
|
|||||||
|
|
||||||
# Handle event props.
|
# Handle event props.
|
||||||
elif isinstance(prop, EventChain):
|
elif isinstance(prop, EventChain):
|
||||||
local_args = ",".join(prop.events[0].local_args)
|
local_args = ",".join(([str(a) for a in prop.events[0].local_args]))
|
||||||
|
|
||||||
if len(prop.events) == 1 and prop.events[0].upload:
|
if len(prop.events) == 1 and prop.events[0].upload:
|
||||||
# Special case for upload events.
|
# Special case for upload events.
|
||||||
|
@ -23,7 +23,7 @@ class Event(Base):
|
|||||||
router_data: Dict[str, Any] = {}
|
router_data: Dict[str, Any] = {}
|
||||||
|
|
||||||
# The event payload.
|
# The event payload.
|
||||||
payload: Dict[str, Any] = {}
|
payload: Dict[Any, Any] = {}
|
||||||
|
|
||||||
|
|
||||||
class EventHandler(Base):
|
class EventHandler(Base):
|
||||||
@ -54,21 +54,18 @@ class EventHandler(Base):
|
|||||||
"""
|
"""
|
||||||
# Get the function args.
|
# Get the function args.
|
||||||
fn_args = inspect.getfullargspec(self.fn).args[1:]
|
fn_args = inspect.getfullargspec(self.fn).args[1:]
|
||||||
|
fn_args = (Var.create_safe(arg) for arg in fn_args)
|
||||||
|
|
||||||
# Construct the payload.
|
# Construct the payload.
|
||||||
values = []
|
values = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
# If it is a Var, add the full name.
|
# Special case for file uploads.
|
||||||
if isinstance(arg, Var):
|
|
||||||
values.append(arg.full_name)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if isinstance(arg, FileUpload):
|
if isinstance(arg, FileUpload):
|
||||||
return EventSpec(handler=self, upload=True)
|
return EventSpec(handler=self, upload=True)
|
||||||
|
|
||||||
# Otherwise, convert to JSON.
|
# Otherwise, convert to JSON.
|
||||||
try:
|
try:
|
||||||
values.append(format.json_dumps(arg))
|
values.append(Var.create(arg))
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
||||||
@ -90,10 +87,10 @@ class EventSpec(Base):
|
|||||||
handler: EventHandler
|
handler: EventHandler
|
||||||
|
|
||||||
# The local arguments on the frontend.
|
# The local arguments on the frontend.
|
||||||
local_args: Tuple[str, ...] = ()
|
local_args: Tuple[Var, ...] = ()
|
||||||
|
|
||||||
# The arguments to pass to the function.
|
# The arguments to pass to the function.
|
||||||
args: Tuple[Any, ...] = ()
|
args: Tuple[Tuple[Var, Var], ...] = ()
|
||||||
|
|
||||||
# Whether to upload files.
|
# Whether to upload files.
|
||||||
upload: bool = False
|
upload: bool = False
|
||||||
@ -142,7 +139,31 @@ class FileUpload(Base):
|
|||||||
|
|
||||||
|
|
||||||
# Special server-side events.
|
# Special server-side events.
|
||||||
def redirect(path: str) -> EventSpec:
|
def server_side(name: str, **kwargs) -> EventSpec:
|
||||||
|
"""A server-side event.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: The name of the event.
|
||||||
|
**kwargs: The arguments to pass to the event.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An event spec for a server-side event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fn():
|
||||||
|
return None
|
||||||
|
|
||||||
|
fn.__qualname__ = name
|
||||||
|
return EventSpec(
|
||||||
|
handler=EventHandler(fn=fn),
|
||||||
|
args=tuple(
|
||||||
|
(Var.create_safe(k), Var.create_safe(v, is_string=type(v) is str))
|
||||||
|
for k, v in kwargs.items()
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def redirect(path: Union[str, Var[str]]) -> EventSpec:
|
||||||
"""Redirect to a new path.
|
"""Redirect to a new path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -151,18 +172,10 @@ def redirect(path: str) -> EventSpec:
|
|||||||
Returns:
|
Returns:
|
||||||
An event to redirect to the path.
|
An event to redirect to the path.
|
||||||
"""
|
"""
|
||||||
|
return server_side("_redirect", path=path)
|
||||||
def fn():
|
|
||||||
return None
|
|
||||||
|
|
||||||
fn.__qualname__ = "_redirect"
|
|
||||||
return EventSpec(
|
|
||||||
handler=EventHandler(fn=fn),
|
|
||||||
args=(("path", path),),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def console_log(message: str) -> EventSpec:
|
def console_log(message: Union[str, Var[str]]) -> EventSpec:
|
||||||
"""Do a console.log on the browser.
|
"""Do a console.log on the browser.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -171,18 +184,10 @@ def console_log(message: str) -> EventSpec:
|
|||||||
Returns:
|
Returns:
|
||||||
An event to log the message.
|
An event to log the message.
|
||||||
"""
|
"""
|
||||||
|
return server_side("_console", message=message)
|
||||||
def fn():
|
|
||||||
return None
|
|
||||||
|
|
||||||
fn.__qualname__ = "_console"
|
|
||||||
return EventSpec(
|
|
||||||
handler=EventHandler(fn=fn),
|
|
||||||
args=(("message", message),),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def window_alert(message: str) -> EventSpec:
|
def window_alert(message: Union[str, Var[str]]) -> EventSpec:
|
||||||
"""Create a window alert on the browser.
|
"""Create a window alert on the browser.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -191,14 +196,21 @@ def window_alert(message: str) -> EventSpec:
|
|||||||
Returns:
|
Returns:
|
||||||
An event to alert the message.
|
An event to alert the message.
|
||||||
"""
|
"""
|
||||||
|
return server_side("_alert", message=message)
|
||||||
|
|
||||||
def fn():
|
|
||||||
return None
|
|
||||||
|
|
||||||
fn.__qualname__ = "_alert"
|
def set_value(ref: str, value: Any) -> EventSpec:
|
||||||
return EventSpec(
|
"""Set the value of a ref.
|
||||||
handler=EventHandler(fn=fn),
|
|
||||||
args=(("message", message),),
|
Args:
|
||||||
|
ref: The ref.
|
||||||
|
value: The value to set.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An event to set the ref.
|
||||||
|
"""
|
||||||
|
return server_side(
|
||||||
|
"_set_value", ref=Var.create_safe(format.format_ref(ref)), value=value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -306,7 +318,7 @@ def call_event_fn(fn: Callable, arg: Var) -> List[EventSpec]:
|
|||||||
return events
|
return events
|
||||||
|
|
||||||
|
|
||||||
def get_handler_args(event_spec: EventSpec, arg: Var) -> Tuple[Tuple[str, str], ...]:
|
def get_handler_args(event_spec: EventSpec, arg: Var) -> Tuple[Tuple[Var, Var], ...]:
|
||||||
"""Get the handler args for the given event spec.
|
"""Get the handler args for the given event spec.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -324,7 +336,7 @@ def get_handler_args(event_spec: EventSpec, arg: Var) -> Tuple[Tuple[str, str],
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Event handler has an invalid signature, needed a method with a parameter, got {event_spec.handler}."
|
f"Event handler has an invalid signature, needed a method with a parameter, got {event_spec.handler}."
|
||||||
)
|
)
|
||||||
return event_spec.args if len(args) > 2 else ((args[1], arg.name),)
|
return event_spec.args if len(args) > 2 else ((Var.create_safe(args[1]), arg),)
|
||||||
|
|
||||||
|
|
||||||
def fix_events(
|
def fix_events(
|
||||||
@ -339,8 +351,6 @@ def fix_events(
|
|||||||
Returns:
|
Returns:
|
||||||
The fixed events.
|
The fixed events.
|
||||||
"""
|
"""
|
||||||
from pynecone.event import Event, EventHandler, EventSpec
|
|
||||||
|
|
||||||
# If the event handler returns nothing, return an empty list.
|
# If the event handler returns nothing, return an empty list.
|
||||||
if events is None:
|
if events is None:
|
||||||
return []
|
return []
|
||||||
@ -359,7 +369,7 @@ def fix_events(
|
|||||||
e = e()
|
e = e()
|
||||||
assert isinstance(e, EventSpec), f"Unexpected event type, {type(e)}."
|
assert isinstance(e, EventSpec), f"Unexpected event type, {type(e)}."
|
||||||
name = format.format_event_handler(e.handler)
|
name = format.format_event_handler(e.handler)
|
||||||
payload = dict(e.args)
|
payload = {k.name: v.name for k, v in e.args}
|
||||||
|
|
||||||
# Create an event and append it to the list.
|
# Create an event and append it to the list.
|
||||||
out.append(
|
out.append(
|
||||||
|
@ -286,7 +286,12 @@ def format_event(event_spec: EventSpec) -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
The compiled event.
|
The compiled event.
|
||||||
"""
|
"""
|
||||||
args = ",".join([":".join((name, val)) for name, val in event_spec.args])
|
args = ",".join(
|
||||||
|
[
|
||||||
|
":".join((name.name, json.dumps(val.name) if val.is_string else val.name))
|
||||||
|
for name, val in event_spec.args
|
||||||
|
]
|
||||||
|
)
|
||||||
return f"E(\"{format_event_handler(event_spec.handler)}\", {wrap(args, '{')})"
|
return f"E(\"{format_event_handler(event_spec.handler)}\", {wrap(args, '{')})"
|
||||||
|
|
||||||
|
|
||||||
@ -398,6 +403,20 @@ def format_state(value: Any) -> Dict:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def format_ref(ref: str) -> str:
|
||||||
|
"""Format a ref.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ref: The ref to format.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The formatted ref.
|
||||||
|
"""
|
||||||
|
# Replace all non-word characters with underscores.
|
||||||
|
clean_ref = re.sub(r"[^\w]+", "_", ref)
|
||||||
|
return f"ref_{clean_ref}"
|
||||||
|
|
||||||
|
|
||||||
def json_dumps(obj: Any) -> str:
|
def json_dumps(obj: Any) -> str:
|
||||||
"""Takes an object and returns a jsonified string.
|
"""Takes an object and returns a jsonified string.
|
||||||
|
|
||||||
|
@ -105,6 +105,24 @@ class Var(ABC):
|
|||||||
|
|
||||||
return BaseVar(name=name, type_=type_, is_local=is_local, is_string=is_string)
|
return BaseVar(name=name, type_=type_, is_local=is_local, is_string=is_string)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_safe(
|
||||||
|
cls, value: Any, is_local: bool = True, is_string: bool = False
|
||||||
|
) -> Var:
|
||||||
|
"""Create a var from a value, guaranteeing that it is not None.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value to create the var from.
|
||||||
|
is_local: Whether the var is local.
|
||||||
|
is_string: Whether the var is a string literal.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The var.
|
||||||
|
"""
|
||||||
|
var = cls.create(value, is_local=is_local, is_string=is_string)
|
||||||
|
assert var is not None
|
||||||
|
return var
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __class_getitem__(cls, type_: str) -> _GenericAlias:
|
def __class_getitem__(cls, type_: str) -> _GenericAlias:
|
||||||
"""Get a typed var.
|
"""Get a typed var.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pynecone"
|
name = "pynecone"
|
||||||
version = "0.1.27"
|
version = "0.1.28"
|
||||||
description = "Web apps in pure Python."
|
description = "Web apps in pure Python."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
authors = [
|
authors = [
|
||||||
|
@ -15,9 +15,9 @@ while ! nc -z localhost 3000 || ! lsof -i :8000 >/dev/null; do
|
|||||||
echo "Error: Server process with PID $pid exited early"
|
echo "Error: Server process with PID $pid exited early"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
if ((wait_time >= 200)); then
|
if ((wait_time >= 300)); then
|
||||||
echo "Error: Timeout waiting for ports 3000 and 8000 to become available"
|
echo "Error: Timeout waiting for ports 3000 and 8000 to become available"
|
||||||
break
|
exit 1
|
||||||
fi
|
fi
|
||||||
sleep 5
|
sleep 5
|
||||||
((wait_time += 5))
|
((wait_time += 5))
|
||||||
|
@ -3,7 +3,7 @@ from typing import Any, Dict
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pynecone.components.tags import CondTag, Tag
|
from pynecone.components.tags import CondTag, Tag
|
||||||
from pynecone.event import EventChain, EventHandler, EventSpec
|
from pynecone.event import EVENT_ARG, EventChain, EventHandler, EventSpec
|
||||||
from pynecone.var import BaseVar, Var
|
from pynecone.var import BaseVar, Var
|
||||||
|
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ def mock_event(arg):
|
|||||||
events=[
|
events=[
|
||||||
EventSpec(
|
EventSpec(
|
||||||
handler=EventHandler(fn=mock_event),
|
handler=EventHandler(fn=mock_event),
|
||||||
local_args=("e",),
|
local_args=(EVENT_ARG,),
|
||||||
args=(("arg", "e.target.value"),),
|
args=((Var.create_safe("arg"), EVENT_ARG.target.value),),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
'{(e) => Event([E("mock_event", {arg:e.target.value})])}',
|
'{(_e) => Event([E("mock_event", {arg:_e.target.value})])}',
|
||||||
),
|
),
|
||||||
({"a": "red", "b": "blue"}, '{{"a": "red", "b": "blue"}}'),
|
({"a": "red", "b": "blue"}, '{{"a": "red", "b": "blue"}}'),
|
||||||
(BaseVar(name="var", type_="int"), "{var}"),
|
(BaseVar(name="var", type_="int"), "{var}"),
|
||||||
|
@ -73,6 +73,9 @@ def test_event_redirect():
|
|||||||
assert isinstance(spec, EventSpec)
|
assert isinstance(spec, EventSpec)
|
||||||
assert spec.handler.fn.__qualname__ == "_redirect"
|
assert spec.handler.fn.__qualname__ == "_redirect"
|
||||||
assert spec.args == (("path", "/path"),)
|
assert spec.args == (("path", "/path"),)
|
||||||
|
assert format.format_event(spec) == 'E("_redirect", {path:"/path"})'
|
||||||
|
spec = event.redirect(Var.create_safe("path"))
|
||||||
|
assert format.format_event(spec) == 'E("_redirect", {path:path})'
|
||||||
|
|
||||||
|
|
||||||
def test_event_console_log():
|
def test_event_console_log():
|
||||||
@ -81,6 +84,9 @@ def test_event_console_log():
|
|||||||
assert isinstance(spec, EventSpec)
|
assert isinstance(spec, EventSpec)
|
||||||
assert spec.handler.fn.__qualname__ == "_console"
|
assert spec.handler.fn.__qualname__ == "_console"
|
||||||
assert spec.args == (("message", "message"),)
|
assert spec.args == (("message", "message"),)
|
||||||
|
assert format.format_event(spec) == 'E("_console", {message:"message"})'
|
||||||
|
spec = event.console_log(Var.create_safe("message"))
|
||||||
|
assert format.format_event(spec) == 'E("_console", {message:message})'
|
||||||
|
|
||||||
|
|
||||||
def test_event_window_alert():
|
def test_event_window_alert():
|
||||||
@ -89,3 +95,22 @@ def test_event_window_alert():
|
|||||||
assert isinstance(spec, EventSpec)
|
assert isinstance(spec, EventSpec)
|
||||||
assert spec.handler.fn.__qualname__ == "_alert"
|
assert spec.handler.fn.__qualname__ == "_alert"
|
||||||
assert spec.args == (("message", "message"),)
|
assert spec.args == (("message", "message"),)
|
||||||
|
assert format.format_event(spec) == 'E("_alert", {message:"message"})'
|
||||||
|
spec = event.window_alert(Var.create_safe("message"))
|
||||||
|
assert format.format_event(spec) == 'E("_alert", {message:message})'
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_value():
|
||||||
|
"""Test the event window alert function."""
|
||||||
|
spec = event.set_value("input1", "")
|
||||||
|
assert isinstance(spec, EventSpec)
|
||||||
|
assert spec.handler.fn.__qualname__ == "_set_value"
|
||||||
|
assert spec.args == (
|
||||||
|
("ref", Var.create_safe("ref_input1")),
|
||||||
|
("value", ""),
|
||||||
|
)
|
||||||
|
assert format.format_event(spec) == 'E("_set_value", {ref:ref_input1,value:""})'
|
||||||
|
spec = event.set_value("input1", Var.create_safe("message"))
|
||||||
|
assert (
|
||||||
|
format.format_event(spec) == 'E("_set_value", {ref:ref_input1,value:message})'
|
||||||
|
)
|
||||||
|
@ -337,3 +337,23 @@ def test_create_config(app_name, expected_config_name, mocker):
|
|||||||
tmpl_mock.format.assert_called_with(
|
tmpl_mock.format.assert_called_with(
|
||||||
app_name=app_name, config_name=expected_config_name
|
app_name=app_name, config_name=expected_config_name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"name,expected",
|
||||||
|
[
|
||||||
|
("input1", "ref_input1"),
|
||||||
|
("input 1", "ref_input_1"),
|
||||||
|
("input-1", "ref_input_1"),
|
||||||
|
("input_1", "ref_input_1"),
|
||||||
|
("a long test?1! name", "ref_a_long_test_1_name"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_format_ref(name, expected):
|
||||||
|
"""Test formatting a ref.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: The name to format.
|
||||||
|
expected: The expected formatted name.
|
||||||
|
"""
|
||||||
|
assert format.format_ref(name) == expected
|
||||||
|
Loading…
Reference in New Issue
Block a user