Skip to content

Commit

Permalink
add StringGetter
Browse files Browse the repository at this point in the history
  • Loading branch information
linkdata committed Feb 28, 2024
1 parent f81f622 commit 0b3e4f4
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 19 deletions.
38 changes: 38 additions & 0 deletions stringgetter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package jaws

import (
"fmt"
"html/template"
)

type StringGetter interface {
JawsGetString(e *Element) string
}

type stringGetter struct{ v string }

func (g stringGetter) JawsGetString(e *Element) string {
return g.v
}

func (g stringGetter) JawsSetString(*Element, string) error {
return ErrValueNotSettable
}

func (g stringGetter) JawsGetTag(rq *Request) any {
return nil
}

func makeStringGetter(v any) StringGetter {
switch v := v.(type) {
case StringGetter:
return v
case string:
return stringGetter{v}
case template.HTML:
return stringGetter{string(v)}
case template.HTMLAttr:
return stringGetter{string(v)}
}
panic(fmt.Errorf("expected jaws.StringGetter or string, not %T", v))
}
88 changes: 88 additions & 0 deletions stringgetter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package jaws

import (
"html/template"
"reflect"
"strings"
"testing"
)

var _ StringGetter = (*testSetter[string])(nil)

func Test_makeStringGetter_panic(t *testing.T) {
defer func() {
if x := recover(); x != nil {
if err, ok := x.(error); ok {
if strings.Contains(err.Error(), "uint32") {
return
}
}
}
t.Fail()
}()
makeStringGetter(uint32(42))
}

func Test_makeStringGetter(t *testing.T) {
val := "<span>"
ts := newTestSetter(val)

tests := []struct {
name string
v any
want StringGetter
out string
err error
tag any
}{
{
name: "StringGetter",
v: ts,
want: ts,
out: val,
tag: ts,
},
{
name: "string",
v: val,
want: stringGetter{val},
out: val,
err: ErrValueNotSettable,
tag: nil,
},
{
name: "template.HTML",
v: template.HTML(val),
want: stringGetter{val},
out: val,
err: ErrValueNotSettable,
tag: nil,
},
{
name: "template.HTMLAttr",
v: template.HTMLAttr(val),
want: stringGetter{val},
out: val,
err: ErrValueNotSettable,
tag: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := makeStringGetter(tt.v)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("makeStringGetter() = %v, want %v", got, tt.want)
}
if out := got.JawsGetString(nil); out != tt.out {
t.Errorf("makeStringGetter().JawsGetString() = %v, want %v", out, tt.out)
}
gotTag := any(got)
if tg, ok := got.(TagGetter); ok {
gotTag = tg.JawsGetTag(nil)
}
if gotTag != tt.tag {
t.Errorf("makeStringGetter().tag = %v, want %v", gotTag, tt.tag)
}
})
}
}
18 changes: 10 additions & 8 deletions stringsetter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,34 @@ import (
)

type StringSetter interface {
JawsGetString(e *Element) string
StringGetter
JawsSetString(e *Element, v string) (err error)
}

type stringGetter struct{ v string }

func (g stringGetter) JawsGetString(e *Element) string {
return g.v
type stringSetter struct {
StringGetter
}

func (g stringGetter) JawsSetString(*Element, string) error {
func (stringSetter) JawsSetString(e *Element, v string) (err error) {
return ErrValueNotSettable
}

func (g stringGetter) JawsGetTag(rq *Request) any {
return nil
func (g stringSetter) JawsGetTag(rq *Request) any {
return g.StringGetter
}

func makeStringSetter(v any) StringSetter {
switch v := v.(type) {
case StringSetter:
return v
case StringGetter:
return stringSetter{v}
case string:
return stringGetter{v}
case template.HTML:
return stringGetter{string(v)}
case template.HTMLAttr:
return stringGetter{string(v)}
case *atomic.Value:
return atomicSetter{v}
}
Expand Down
62 changes: 56 additions & 6 deletions stringsetter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,36 @@ func Test_makeStringSetter_panic(t *testing.T) {
makeStringSetter(uint32(42))
}

type simpleGetter struct {
Value string
}

func (g simpleGetter) JawsGetString(e *Element) string {
return g.Value
}

type simpleNotagGetter struct {
v string
}

func (g simpleNotagGetter) JawsGetString(e *Element) string {
return g.v
}

func (g simpleNotagGetter) JawsGetTag(rq *Request) any {
return nil
}

func Test_makeStringSetter(t *testing.T) {
val := "<span>"
var av atomic.Value
av.Store(val)
ts := newTestSetter(val)

sg := simpleGetter{Value: val}

sng := simpleNotagGetter{v: val}

tests := []struct {
name string
v any
Expand All @@ -38,13 +62,29 @@ func Test_makeStringSetter(t *testing.T) {
err error
tag any
}{
{
name: "StringGetter_untagged",
v: sng,
want: stringSetter{sng},
out: val,
err: ErrValueNotSettable,
tag: nil,
},
{
name: "StringSetter",
v: ts,
want: ts,
out: val,
tag: ts,
},
{
name: "StringGetter",
v: sg,
want: stringSetter{sg},
out: val,
err: ErrValueNotSettable,
tag: sg,
},
{
name: "string",
v: val,
Expand All @@ -61,6 +101,14 @@ func Test_makeStringSetter(t *testing.T) {
err: ErrValueNotSettable,
tag: nil,
},
{
name: "template.HTMLAttr",
v: template.HTMLAttr(val),
want: stringGetter{val},
out: val,
err: ErrValueNotSettable,
tag: nil,
},
{
name: "*atomic.Value",
v: &av,
Expand All @@ -81,12 +129,14 @@ func Test_makeStringSetter(t *testing.T) {
if err := got.JawsSetString(nil, "str"); err != tt.err {
t.Errorf("makeStringSetter().JawsSetString() = %v, want %v", err, tt.err)
}
gotTag := any(got)
if tg, ok := got.(TagGetter); ok {
gotTag = tg.JawsGetTag(nil)
}
if gotTag != tt.tag {
t.Errorf("makeStringSetter().tag = %v, want %v", gotTag, tt.tag)

gotTag := MustTagExpand(nil, got)
if len(gotTag) == 1 {
if gotTag[0] != tt.tag {
t.Errorf("makeStringSetter().tag = %v, want %v", gotTag, tt.tag)
}
} else if tt.tag != nil {
t.Error(len(gotTag))
}
})
}
Expand Down
10 changes: 5 additions & 5 deletions uiimg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (

type UiImg struct {
UiHtml
StringSetter
StringGetter
}

func (ui *UiImg) JawsRender(e *Element, w io.Writer, params []any) error {
ui.parseGetter(e, ui.StringSetter)
ui.parseGetter(e, ui.StringGetter)
srcattr := template.HTMLAttr("src=" + strconv.Quote(ui.JawsGetString(e))) // #nosec G203
attrs := append(e.ParseParams(params), srcattr)
return WriteHtmlInner(w, e.Jid(), "img", "", "", attrs...)
Expand All @@ -22,12 +22,12 @@ func (ui *UiImg) JawsUpdate(e *Element) {
e.SetAttr("src", ui.JawsGetString(e))
}

func NewUiImg(g StringSetter) *UiImg {
func NewUiImg(g StringGetter) *UiImg {
return &UiImg{
StringSetter: g,
StringGetter: g,
}
}

func (rq RequestWriter) Img(imageSrc any, params ...any) error {
return rq.UI(NewUiImg(makeStringSetter(imageSrc)), params...)
return rq.UI(NewUiImg(makeStringGetter(imageSrc)), params...)
}

0 comments on commit 0b3e4f4

Please sign in to comment.