89 lines
2.9 KiB
Go
89 lines
2.9 KiB
Go
package webui
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"kjol/wasmruntime/vdom"
|
|
)
|
|
|
|
// The pad's value IS the markup it shows — that is the whole reason it draws into an SVG
|
|
// rather than a canvas. If the two could differ, the user would sign one thing and the
|
|
// caller would store another.
|
|
func TestSignaturePadValueIsWhatIsDrawn(t *testing.T) {
|
|
var got string
|
|
pad := NewSignaturePad(SignaturePadOptions{OnChange: func(svg string) { got = svg }})
|
|
|
|
pad.strokes.Set([]sigStroke{{{X: 10, Y: 20}, {X: 30, Y: 40}, {X: 50, Y: 20}}})
|
|
|
|
value := pad.SVG()
|
|
shown := vdom.RenderHTML(pad.Render(SignaturePadProps{}))
|
|
|
|
// Every path in the value is present in the rendered element.
|
|
paths := sigPaths(pad.strokes.Get())
|
|
if paths == "" {
|
|
t.Fatal("no path was generated for a three-point stroke")
|
|
}
|
|
if !strings.Contains(value, paths) {
|
|
t.Error("the emitted SVG does not contain the strokes it was built from")
|
|
}
|
|
if !strings.Contains(shown, `d="M10,20`) {
|
|
t.Errorf("the rendered pad is not showing the stroke:\n%s", shown)
|
|
}
|
|
_ = got
|
|
}
|
|
|
|
// An empty pad is an empty string, not a blank drawing. A caller storing the value must
|
|
// be able to ask "did they sign?" without parsing SVG.
|
|
func TestSignaturePadEmptyIsEmptyString(t *testing.T) {
|
|
pad := NewSignaturePad(SignaturePadOptions{})
|
|
if !pad.IsEmpty() {
|
|
t.Error("a fresh pad should be empty")
|
|
}
|
|
if pad.SVG() != "" {
|
|
t.Errorf("an empty pad produced %q, want \"\"", pad.SVG())
|
|
}
|
|
}
|
|
|
|
// Clear reports the emptiness to the caller. Without the callback a cleared pad would
|
|
// leave the last signature sitting in whatever the caller stored it in.
|
|
func TestSignaturePadClearNotifies(t *testing.T) {
|
|
got := "not called"
|
|
pad := NewSignaturePad(SignaturePadOptions{OnChange: func(svg string) { got = svg }})
|
|
pad.strokes.Set([]sigStroke{{{X: 1, Y: 1}, {X: 2, Y: 2}}})
|
|
|
|
pad.Clear()
|
|
|
|
if got != "" {
|
|
t.Errorf("OnChange got %q on clear, want \"\"", got)
|
|
}
|
|
if !pad.IsEmpty() {
|
|
t.Error("the pad is not empty after Clear")
|
|
}
|
|
}
|
|
|
|
// A single point is a tap, not a mark: it has no length, produces no path, and must not
|
|
// count as a signature.
|
|
func TestSignaturePadIgnoresSinglePointStrokes(t *testing.T) {
|
|
if got := sigPaths([]sigStroke{{{X: 5, Y: 5}}}); got != "" {
|
|
t.Errorf("a one-point stroke produced a path: %q", got)
|
|
}
|
|
}
|
|
|
|
// Two points are a straight line; three or more are smoothed into curves. Handwriting
|
|
// drawn as raw polylines looks like a seismograph.
|
|
func TestSignaturePadSmoothsLongStrokes(t *testing.T) {
|
|
line := sigPaths([]sigStroke{{{X: 0, Y: 0}, {X: 10, Y: 10}}})
|
|
if !strings.Contains(line, " L10,10") {
|
|
t.Errorf("a two-point stroke should be a straight line: %q", line)
|
|
}
|
|
if strings.Contains(line, "Q") {
|
|
t.Errorf("a two-point stroke has nothing to smooth: %q", line)
|
|
}
|
|
|
|
curve := sigPaths([]sigStroke{{{X: 0, Y: 0}, {X: 10, Y: 10}, {X: 20, Y: 0}}})
|
|
if !strings.Contains(curve, "Q") {
|
|
t.Errorf("a three-point stroke should be smoothed: %q", curve)
|
|
}
|
|
}
|