Current section
Files
Jump to
Current section
Files
src/novdom_testing/component_should.gleam
//// A module for testing novdom components. \
//// Use it in combination with `novdom_testing/testing` to test initilize tests and render components.
import gleam/string
import novdom/internals/component.{type Component}
import novdom/internals/parameter.{
type Event, type Parameter, Attribute, Listener,
}
/// Check if a component is visible to the user.
pub fn be_visible(component: Component) -> Component {
case component_visible_js(component) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" is not visible",
])
}
}
/// Check if a component is hidden from the user. This is the opposite of `be_visible`
pub fn be_hidden(component: Component) -> Component {
case component_visible_js(component) {
False -> component
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" is visible",
])
}
}
/// Check if a component has a specific attribute.
pub fn have_attribute(component: Component, attribute: Parameter) -> Component {
let assert Attribute(key, value) = attribute
case has_attribute_js(component, key, value) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" does not have ",
key,
" \"",
value,
"\"",
])
}
}
/// Check if a component does not have a specific attribute. This is the opposite of `have_attribute`
pub fn not_have_attribute(
component: Component,
attribute: Parameter,
) -> Component {
let assert Attribute(key, value) = attribute
case has_attribute_js(component, key, value) {
False -> component
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" has ",
key,
" \"",
value,
"\"",
])
}
}
/// Check if a component has a specific listener (callback is not checked). \
/// If a specific callback needs to be checked, use `have_listener_callback`.
pub fn have_listener(
component: Component,
listener_fn: fn(fn(Event) -> Nil) -> Parameter,
) -> Component {
case has_listener_js(component, listener_fn) {
#(True, _) -> component
#(False, name) ->
panic as string.concat([
"\n",
current_step(),
":\n",
component |> description("Component"),
"does not have listener \"",
name,
"\"",
])
}
}
/// Check if a component does not have a specific listener. This is the opposite of `have_listener`
pub fn not_have_listener(
component: Component,
listener_fn: fn(fn(Event) -> Nil) -> Parameter,
) -> Component {
case has_listener_js(component, listener_fn) {
#(False, _) -> component
#(True, name) ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" has listener \"",
name,
"\"",
])
}
}
/// Check if a component has a specific listener with a specific callback. \
/// If only the listener needs to be checked, use `have_listener`.
pub fn have_listener_callback(
component: Component,
listener: Parameter,
) -> Component {
let assert Listener(name, callback) = listener
case has_listener_callback_js(component, name, callback) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" does not have listener \"",
name,
"\" with specified callback",
])
}
}
/// Check if a component does not have a specific listener with a specific callback. This is the opposite of `have_listener_callback`
pub fn not_have_listener_callback(
component: Component,
listener: Parameter,
) -> Component {
let assert Listener(name, callback) = listener
case has_listener_callback_js(component, name, callback) {
False -> component
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" has listener \"",
name,
"\" with specified callback",
])
}
}
/// Check if a component has a specific child.
pub fn have_child(parent: Component, child: Component) -> Component {
case has_child_js(parent, child) {
True -> parent
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
parent |> description("Component"),
" does not have specified ",
child |> description("child"),
])
}
}
/// Check if a component does not have a specific child. This is the opposite of `have_child`
pub fn not_have_child(parent: Component, child: Component) -> Component {
case has_child_js(parent, child) {
False -> parent
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
parent |> description("Component"),
" has specified ",
child |> description("child"),
])
}
}
/// Check if a component shows a specific text.
pub fn show_text(component: Component, text: String) -> Component {
case shows_text_js(component, text) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" does not show text \"",
text,
"\"",
])
}
}
/// Check if a component exclusively shows a specific text.
pub fn exclusively_show_text(component: Component, text: String) -> Component {
case exclusively_shows_text_js(component, text) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" does not exclusively show text \"",
text,
"\"",
])
}
}
/// Check if a component does not show a specific text. This is the opposite of `show_text`
pub fn not_show_text(component: Component, text: String) -> Component {
case shows_text_js(component, text) {
False -> component
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" shows text \"",
text,
"\"",
])
}
}
/// Check if a component has a specific HTML tag.
pub fn have_tag(component: Component, tag: String) -> Component {
case has_tag_js(component, tag) {
True -> component
False ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" does not have tag \"",
tag,
"\"",
])
}
}
/// Check if a component does not have a specific HTML tag. This is the opposite of `have_tag`
pub fn not_have_tag(component: Component, tag: String) -> Component {
case has_tag_js(component, tag) {
False -> component
True ->
panic as string.concat([
"\n",
current_step(),
":\n ",
component |> description("Component"),
" has tag \"",
tag,
"\"",
])
}
}
/// Returns the value of an attribute
@external(javascript, "../testing_ffi.mjs", "attribute")
pub fn attribute(component: Component, name: String) -> String
@external(javascript, "../testing_ffi.mjs", "component_visible")
fn component_visible_js(component: Component) -> Bool
@external(javascript, "../testing_ffi.mjs", "has_attribute")
fn has_attribute_js(component: Component, key: String, value: String) -> Bool
@external(javascript, "../testing_ffi.mjs", "has_listener")
fn has_listener_js(
component: Component,
listener_fn: fn(fn(Event) -> Nil) -> Parameter,
) -> #(Bool, String)
@external(javascript, "../testing_ffi.mjs", "has_listener_callback")
fn has_listener_callback_js(
component: Component,
name: String,
callback: fn(Event) -> Nil,
) -> Bool
@external(javascript, "../testing_ffi.mjs", "has_child")
fn has_child_js(component: Component, child: Component) -> Bool
@external(javascript, "../testing_ffi.mjs", "shows_text")
fn shows_text_js(component: Component, text: String) -> Bool
@external(javascript, "../testing_ffi.mjs", "exclusively_shows_text")
fn exclusively_shows_text_js(component: Component, text: String) -> Bool
@external(javascript, "../testing_ffi.mjs", "has_tag")
fn has_tag_js(component: Component, tag: String) -> Bool
@external(javascript, "../testing_ffi.mjs", "current_step")
fn current_step() -> String
@external(javascript, "../testing_ffi.mjs", "get_description")
fn description(component: Component, default: String) -> String