Skip to content

Commit

Permalink
add checkhashable
Browse files Browse the repository at this point in the history
  • Loading branch information
linkdata committed Mar 7, 2024
1 parent 6cd1cc7 commit 83bb8d6
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 24 deletions.
34 changes: 34 additions & 0 deletions checkhashable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package jaws

import "fmt"

type errNotHashableType struct {
s string
}

func (e errNotHashableType) Error() string {
return fmt.Sprintf("not hashable type %s", e.s)
}

func (errNotHashableType) Is(other error) bool {
return other == ErrIllegalTagType
}

func newErrNotHashableType(tag any) error {
return errNotHashableType{
s: fmt.Sprintf("%T", tag),
}
}

var ErrNotHashableType = errNotHashableType{}

func checkHashable(tag any) (err error) {
defer func() {
if recover() != nil {
err = newErrNotHashableType(tag)
}
}()
tmp := map[any]struct{}{}
tmp[tag] = struct{}{}
return
}
2 changes: 1 addition & 1 deletion container.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package jaws

type Container interface {
// JawsContains must return a slice of UI objects. The slice contents must not be modified after returning it.
// JawsContains must return a slice of hashable UI objects. The slice contents must not be modified after returning it.
JawsContains(e *Element) (contents []UI)
}
16 changes: 3 additions & 13 deletions tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,6 @@ func (errIllegalTagType) Is(other error) bool {

var ErrIllegalTagType = errIllegalTagType{}

func checkHashable(tag any) (yes bool) {
defer func() {
if recover() == nil {
yes = true
}
}()
tmp := map[any]struct{}{}
tmp[tag] = struct{}{}
return
}

func tagExpand(l int, rq *Request, tag any, result []any) ([]any, error) {
if l > 10 || len(result) > 100 {
return result, ErrTooManyTags
Expand Down Expand Up @@ -96,9 +85,10 @@ func tagExpand(l int, rq *Request, tag any, result []any) ([]any, error) {
}
return result, err
default:
if checkHashable(data) {
return append(result, data), nil
if err := checkHashable(data); err != nil {
return result, err
}
return append(result, data), nil
}
return result, errIllegalTagType{tag: tag}
}
Expand Down
2 changes: 1 addition & 1 deletion ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,6 @@ func TestRequest_InsideTemplate(t *testing.T) {
}
w.Flush()
if x := w.Body.String(); x != want {
t.Errorf("%q", x)
t.Errorf("mismatch:\nwant %q\n got %q", want, x)
}
}
24 changes: 22 additions & 2 deletions uicontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ func (tc *testContainer) JawsContains(e *Element) (contents []UI) {
var _ Container = &testContainer{}

func TestRequest_Container(t *testing.T) {
notHashableUI := struct {
*UiSpan
x map[int]int
}{
UiSpan: NewUiSpan(testHtmlGetter("foo")),
x: map[int]int{},
}

type args struct {
c Container
params []any
Expand All @@ -29,6 +37,7 @@ func TestRequest_Container(t *testing.T) {
name string
args args
want template.HTML
err error
}{
{
name: "empty",
Expand All @@ -54,15 +63,26 @@ func TestRequest_Container(t *testing.T) {
},
want: `<div id="Jid.1" hidden><span id="Jid.2">foo</span><span id="Jid.3">bar</span></div>`,
},
{
name: "nonhashable",
args: args{
c: &testContainer{[]UI{notHashableUI}},
},
err: newErrNotHashableType(notHashableUI),
want: `<div id="Jid.1"></div>`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nextJid = 0
rq := newTestRequest()
defer rq.Close()
rq.Container("div", tt.args.c, tt.args.params...)
err := rq.Container("div", tt.args.c, tt.args.params...)
if err != tt.err {
t.Errorf("got error %v, wanted %v", err, tt.err)
}
if got := rq.BodyHtml(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Request.Container() = %v, want %v", got, tt.want)
t.Errorf("Request.Container()\nwant %v\n got %v", tt.want, got)
}
})
}
Expand Down
16 changes: 9 additions & 7 deletions uiwrapcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type uiWrapContainer struct {
contents []*Element
}

func (ui *uiWrapContainer) renderContainer(e *Element, w io.Writer, outerhtmltag string, params []any) error {
func (ui *uiWrapContainer) renderContainer(e *Element, w io.Writer, outerhtmltag string, params []any) (err error) {
ui.parseGetter(e, ui.Container)
attrs := e.ParseParams(params)
b := e.Jid().AppendStartTagAttr(nil, outerhtmltag)
Expand All @@ -25,21 +25,23 @@ func (ui *uiWrapContainer) renderContainer(e *Element, w io.Writer, outerhtmltag
b = append(b, attr...)
}
b = append(b, '>')
_, err := w.Write(b)
_, err = w.Write(b)
if err == nil {
for _, cui := range ui.Container.JawsContains(e) {
if err == nil {
elem := e.Request.NewElement(cui)
ui.contents = append(ui.contents, elem)
err = elem.JawsRender(w, nil)
if err = checkHashable(cui); err == nil {
elem := e.Request.NewElement(cui)
ui.contents = append(ui.contents, elem)
err = elem.JawsRender(w, nil)
}
}
}
b = b[:0]
b = append(b, "</"...)
b = append(b, outerhtmltag...)
b = append(b, '>')
if err == nil {
_, err = w.Write(b)
if _, err2 := w.Write(b); err == nil {
err = err2
}
}
return err
Expand Down

0 comments on commit 83bb8d6

Please sign in to comment.