v4, beta4 (#19)

- Update with header/attribute changes between alpha8 and beta4
- Add support for htmax script, attributes, headers, and extension config

Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
2026-06-15 01:07:38 +00:00
parent d4a7e0c9ce
commit 5c12ad7cef
22 changed files with 1066 additions and 214 deletions
+335
View File
@@ -0,0 +1,335 @@
module ViewEngineMax
open Expecto
open Giraffe.ViewEngine.Htmax
/// Tests for the HxBrowserIndicatorConfigItem type
let hxBrowserIndicatorConfigItem =
testList "HxBrowserIndicatorConfigItem" [
testList "ToHcon" [
test "succeeds for BoostBrowserIndicator" {
Expect.equal
((BoostBrowserIndicator false).ToHcon())
"boostBrowserIndicator:false"
"The HCON value was incorrect"
}
]
]
/// Tests for the HxPreloadConfigItem type
let hxPreloadConfigItem =
testList "HxPreloadConfigItem" [
testList "ToHcon" [
test "succeeds for AutoBoost" {
Expect.equal ((AutoBoost false).ToHcon()) "autoBoost:false" "The HCON value was incorrect"
}
test "succeeds for BoostEvent" {
Expect.equal ((BoostEvent "mouseover").ToHcon()) "boostEvent:mouseover" "The HCON value was incorrect"
}
test "succeeds for BoostTimeout" {
Expect.equal ((BoostTimeout 30_000).ToHcon()) "boostTimeout:30000" "The HCON value was incorrect"
}
]
]
/// Tests for the HxSseWsConfigItem type
let hxSseWsConfigItem =
testList "HxSseWsConfigItem" [
testList "ToHcon" [
test "succeeds for Reconnect" {
Expect.equal ((Reconnect true).ToHcon()) "reconnect:true" "The HCON value was incorrect"
}
testList "ReconnectDelay" [
test "succeeds for numeric value" {
Expect.equal ((ReconnectDelay "3000").ToHcon()) "reconnectDelay:3000" "The HCON value was incorrect"
}
test "succeeds for value with units" {
Expect.equal ((ReconnectDelay "3s").ToHcon()) "reconnectDelay:3s" "The HCON value was incorrect"
}
]
testList "ReconnectMaxDelay" [
test "succeeds for numeric value" {
Expect.equal
((ReconnectMaxDelay "30000").ToHcon()) "reconnectMaxDelay:30000" "The HCON value was incorrect"
}
test "succeeds for value with units" {
Expect.equal
((ReconnectMaxDelay "50s").ToHcon()) "reconnectMaxDelay:50s" "The HCON value was incorrect"
}
]
testList "ReconnectMaxAttempts" [
test "succeeds for negative 1" {
Expect.equal
((ReconnectMaxAttempts -1).ToHcon())
"reconnectMaxAttempts:Infinity"
"The HCON value was incorrect"
}
test "succeeds for zero" {
Expect.equal
((ReconnectMaxAttempts 0).ToHcon()) "reconnectMaxAttempts:0" "The HCON value was incorrect"
}
test "succeeds for positive number" {
Expect.equal
((ReconnectMaxAttempts 7).ToHcon()) "reconnectMaxAttempts:7" "The HCON value was incorrect"
}
]
test "succeeds for ReconnectJitter" {
Expect.equal ((ReconnectJitter 0.7).ToHcon()) "reconnectJitter:0.7" "The HCON value was incorrect"
}
test "succeeds for PauseOnBackground" {
Expect.equal
((PauseOnBackground false).ToHcon()) "pauseOnBackground:false" "The HCON value was incorrect"
}
test "succeeds for PendingRequestTtl" {
Expect.equal ((PendingRequestTtl 5000).ToHcon()) "pendingRequestTTL:5000" "The HCON value was incorrect"
}
]
]
/// Tests for the HxConfig module
let hxConfig =
testList "HxConfig" [
test "hxBrowserIndicatorConfig succeeds" {
Expect.equal
(hxBrowserIndicatorConfig [ BoostBrowserIndicator true ])
"browser-indicator.boostBrowserIndicator:true"
"Config settings not correct"
}
test "hxPreloadConfig succeeds" {
Expect.equal
(hxPreloadConfig [ AutoBoost true; BoostTimeout 3_000 ])
"preload.autoBoost:true preload.boostTimeout:3000"
"Config settings not correct"
}
test "hxSseConfig succeeds" {
Expect.equal
(hxSseConfig [ ReconnectDelay "5s"; PauseOnBackground false ])
"sse.reconnectDelay:5s sse.pauseOnBackground:false"
"Config settings not correct"
}
test "hxWsConfig succeeds" {
Expect.equal
(hxWsConfig [ Reconnect false; PendingRequestTtl 40_000 ])
"ws.reconnect:false ws.pendingRequestTTL:40000"
"Config settings not correct"
}
]
/// Tests for the HxEvent module
let hxEvent =
testList "HxEvent" [
testList "AfterSseConnection" [
test "ToString succeeds" {
Expect.equal
(string AfterSseConnection) "afterSseConnection" "AfterSseConnection event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(AfterSseConnection.ToHxOnString())
"after:sse:connection"
"AfterSseConnection hx-on event name not correct"
}
]
testList "AfterSseMessage" [
test "ToString succeeds" {
Expect.equal (string AfterSseMessage) "afterSseMessage" "AfterSseMessage event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(AfterSseMessage.ToHxOnString()) "after:sse:message" "AfterSseMessage hx-on event name not correct"
}
]
testList "AfterWsConnection" [
test "ToString succeeds" {
Expect.equal
(string AfterWsConnection) "afterWsConnection" "AfterWsConnection event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(AfterWsConnection.ToHxOnString())
"after:ws:connection"
"AfterWsConnection hx-on event name not correct"
}
]
testList "AfterWsMessage" [
test "ToString succeeds" {
Expect.equal (string AfterWsMessage) "afterWsMessage" "AfterWsMessage event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(AfterWsMessage.ToHxOnString()) "after:ws:message" "AfterWsMessage hx-on event name not correct"
}
]
testList "AfterWsRequest" [
test "ToString succeeds" {
Expect.equal (string AfterWsRequest) "afterWsRequest" "AfterWsRequest event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(AfterWsRequest.ToHxOnString()) "after:ws:request" "AfterWsRequest hx-on event name not correct"
}
]
testList "BeforeSseConnection" [
test "ToString succeeds" {
Expect.equal
(string BeforeSseConnection) "beforeSseConnection" "BeforeSseConnection event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(BeforeSseConnection.ToHxOnString())
"before:sse:connection"
"BeforeSseConnection hx-on event name not correct"
}
]
testList "BeforeSseMessage" [
test "ToString succeeds" {
Expect.equal (string BeforeSseMessage) "beforeSseMessage" "BeforeSseMessage event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(BeforeSseMessage.ToHxOnString())
"before:sse:message"
"BeforeSseMessage hx-on event name not correct"
}
]
testList "BeforeWsConnection" [
test "ToString succeeds" {
Expect.equal
(string BeforeWsConnection) "beforeWsConnection" "BeforeWsConnection event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(BeforeWsConnection.ToHxOnString())
"before:ws:connection"
"BeforeWsConnection hx-on event name not correct"
}
]
testList "BeforeWsMessage" [
test "ToString succeeds" {
Expect.equal (string BeforeWsMessage) "beforeWsMessage" "BeforeWsMessage event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(BeforeWsMessage.ToHxOnString()) "before:ws:message" "BeforeWsMessage hx-on event name not correct"
}
]
testList "BeforeWsRequest" [
test "ToString succeeds" {
Expect.equal (string BeforeWsRequest) "beforeWsRequest" "BeforeWsRequest event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(BeforeWsRequest.ToHxOnString()) "before:ws:request" "BeforeWsRequest hx-on event name not correct"
}
]
testList "DownloadComplete" [
test "ToString succeeds" {
Expect.equal (string DownloadComplete) "downloadComplete" "DownloadComplete event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(DownloadComplete.ToHxOnString())
"download:complete"
"DownloadComplete hx-on event name not correct"
}
]
testList "DownloadProgress" [
test "ToString succeeds" {
Expect.equal (string DownloadProgress) "downloadProgress" "DownloadProgress event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(DownloadProgress.ToHxOnString())
"download:progress"
"DownloadProgress hx-on event name not correct"
}
]
testList "DownloadStart" [
test "ToString succeeds" {
Expect.equal (string DownloadStart) "downloadStart" "DownloadStart event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal
(DownloadStart.ToHxOnString()) "download:start" "DownloadStart hx-on event name not correct"
}
]
testList "SseClose" [
test "ToString succeeds" {
Expect.equal (string SseClose) "sseClose" "SseClose event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal (SseClose.ToHxOnString()) "sse:close" "SseClose hx-on event name not correct"
}
]
testList "SseError" [
test "ToString succeeds" {
Expect.equal (string SseError) "sseError" "SseError event name not correct"
}
test "ToHxOnString succeeds" {
Expect.equal (SseError.ToHxOnString()) "sse:error" "SseError hx-on event name not correct"
}
]
]
open Giraffe.ViewEngine
/// Pipe-able assertion for a rendered node
let shouldRender expected node =
Expect.equal (RenderView.AsString.htmlNode node) expected "Rendered HTML incorrect"
/// Tests for the HtmaxAttrs module
let attributes =
testList "Attributes" [
test "_hxBrowserIndicator succeeds" {
a [ _hxBrowserIndicator ] [] |> shouldRender """<a hx-browser-indicator="true"></a>"""
}
test "_hxLive succeeds" {
main [ _hxLive "q().doStuff()" ] [] |> shouldRender """<main hx-live="q().doStuff()"></main>"""
}
test "_hxOnMax succeeds" {
body [ _hxOnMax SseClose "alert(done)" ] []
|> shouldRender """<body hx-on:htmx:sse:close="alert(done)"></body>"""
}
testList "_hxPreload" [
test "succeeds when given an event" {
blockquote [ _hxPreload (Some "focus") ] []
|> shouldRender """<blockquote hx-preload="focus"></blockquote>"""
}
test "succeeds when not given an event" {
em [ _hxPreload None ] [] |> shouldRender """<em hx-preload></em>"""
}
]
test "_hxSseClose succeeds" {
form [ _hxSseClose "fin" ] [] |> shouldRender """<form hx-sse:close="fin"></form>"""
}
test "_hxSseConnect succeeds" {
div [ _hxSseConnect "/path/to/resource" ] []
|> shouldRender """<div hx-sse:connect="/path/to/resource"></div>"""
}
test "_hxTargets succeeds" {
dl [ _hxTargets ".ephemeral" ] [] |> shouldRender """<dl hx-targets=".ephemeral"></dl>"""
}
test "_hxWsConnect succeeds" {
p [ _hxWsConnect "/over/here" ] [] |> shouldRender """<p hx-ws:connect="/over/here"></p>"""
}
testList "_hxWsSend" [
test "succeeds when given a URL" {
span [ _hxWsSend (Some "/a/new/place") ] []
|> shouldRender """<span hx-ws:send="/a/new/place"></span>"""
}
test "succeeds when not given a URL" {
aside [ _hxWsSend None ] [] |> shouldRender """<aside hx-ws:send></aside>"""
}
]
]
let allTests =
testList "ViewEngine.Htmax" [
hxBrowserIndicatorConfigItem
hxPreloadConfigItem
hxSseWsConfigItem
hxConfig
hxEvent
attributes
]