fix(conventions): isolate banned imports and clarify tests
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
b3f622988d
commit
8a3f28aff3
13 changed files with 62 additions and 26 deletions
|
|
@ -1,7 +1,7 @@
|
|||
package html
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
i18n "dappco.re/go/core/i18n"
|
||||
|
|
@ -100,7 +100,7 @@ func BenchmarkImprint_Small(b *testing.B) {
|
|||
func BenchmarkImprint_Large(b *testing.B) {
|
||||
items := make([]string, 20)
|
||||
for i := range items {
|
||||
items[i] = fmt.Sprintf("Item %d was created successfully", i)
|
||||
items[i] = "Item " + strconv.Itoa(i) + " was created successfully"
|
||||
}
|
||||
page := NewLayout("HLCRF").
|
||||
H(El("h1", Text("Building project"))).
|
||||
|
|
@ -207,7 +207,7 @@ func BenchmarkLayout_Nested(b *testing.B) {
|
|||
func BenchmarkLayout_ManySlotChildren(b *testing.B) {
|
||||
nodes := make([]Node, 50)
|
||||
for i := range nodes {
|
||||
nodes[i] = El("p", Raw(fmt.Sprintf("paragraph %d", i)))
|
||||
nodes[i] = El("p", Raw("paragraph "+strconv.Itoa(i)))
|
||||
}
|
||||
layout := NewLayout("HLCRF").
|
||||
H(Raw("header")).
|
||||
|
|
@ -242,7 +242,7 @@ func benchEach(b *testing.B, n int) {
|
|||
items[i] = i
|
||||
}
|
||||
node := Each(items, func(i int) Node {
|
||||
return El("li", Raw(fmt.Sprintf("item-%d", i)))
|
||||
return El("li", Raw("item-"+strconv.Itoa(i)))
|
||||
})
|
||||
ctx := NewContext()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !js
|
||||
|
||||
// Package main provides a build-time CLI for generating Web Component JS bundles.
|
||||
// Reads a JSON slot map from stdin, writes the generated JS to stdout.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !js
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
|
@ -9,7 +11,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRun_Good(t *testing.T) {
|
||||
func TestRun_WritesBundle(t *testing.T) {
|
||||
input := strings.NewReader(`{"H":"nav-bar","C":"main-content"}`)
|
||||
var output bytes.Buffer
|
||||
|
||||
|
|
@ -23,7 +25,7 @@ func TestRun_Good(t *testing.T) {
|
|||
assert.Equal(t, 2, strings.Count(js, "extends HTMLElement"))
|
||||
}
|
||||
|
||||
func TestRun_Bad_InvalidJSON(t *testing.T) {
|
||||
func TestRun_InvalidJSON(t *testing.T) {
|
||||
input := strings.NewReader(`not json`)
|
||||
var output bytes.Buffer
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ func TestRun_Bad_InvalidJSON(t *testing.T) {
|
|||
assert.Contains(t, err.Error(), "invalid JSON")
|
||||
}
|
||||
|
||||
func TestRun_Bad_InvalidTag(t *testing.T) {
|
||||
func TestRun_InvalidTag(t *testing.T) {
|
||||
input := strings.NewReader(`{"H":"notag"}`)
|
||||
var output bytes.Buffer
|
||||
|
||||
|
|
@ -41,7 +43,7 @@ func TestRun_Bad_InvalidTag(t *testing.T) {
|
|||
assert.Contains(t, err.Error(), "hyphen")
|
||||
}
|
||||
|
||||
func TestRun_Good_Empty(t *testing.T) {
|
||||
func TestRun_EmptySlots(t *testing.T) {
|
||||
input := strings.NewReader(`{}`)
|
||||
var output bytes.Buffer
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBuildComponentJS_Good(t *testing.T) {
|
||||
func TestBuildComponentJS_ValidJSON(t *testing.T) {
|
||||
slotsJSON := `{"H":"nav-bar","C":"main-content"}`
|
||||
js, err := buildComponentJS(slotsJSON)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -18,7 +18,7 @@ func TestBuildComponentJS_Good(t *testing.T) {
|
|||
assert.Contains(t, js, "customElements.define")
|
||||
}
|
||||
|
||||
func TestBuildComponentJS_Bad_InvalidJSON(t *testing.T) {
|
||||
func TestBuildComponentJS_InvalidJSON(t *testing.T) {
|
||||
_, err := buildComponentJS("not json")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const (
|
|||
wasmRawLimit = 3_670_016 // 3.5 MB raw size limit
|
||||
)
|
||||
|
||||
func TestWASMBinarySize_Good(t *testing.T) {
|
||||
func TestWASMBinarySize_WithinBudget(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping WASM build test in short mode")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !js
|
||||
|
||||
package codegen
|
||||
|
||||
import "testing"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
//go:build !js
|
||||
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ func GenerateClass(tag, slot string) (string, error) {
|
|||
|
||||
// GenerateRegistration produces the customElements.define() call.
|
||||
func GenerateRegistration(tag, className string) string {
|
||||
return fmt.Sprintf(`customElements.define("%s", %s);`, tag, className)
|
||||
return `customElements.define("` + tag + `", ` + className + `);`
|
||||
}
|
||||
|
||||
// TagToClassName converts a kebab-case tag to PascalCase class name.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !js
|
||||
|
||||
package codegen
|
||||
|
||||
import (
|
||||
|
|
@ -8,7 +10,7 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGenerateClass_Good(t *testing.T) {
|
||||
func TestGenerateClass_ValidTag(t *testing.T) {
|
||||
js, err := GenerateClass("photo-grid", "C")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, js, "class PhotoGrid extends HTMLElement")
|
||||
|
|
@ -17,19 +19,19 @@ func TestGenerateClass_Good(t *testing.T) {
|
|||
assert.Contains(t, js, "photo-grid")
|
||||
}
|
||||
|
||||
func TestGenerateClass_Bad_InvalidTag(t *testing.T) {
|
||||
func TestGenerateClass_InvalidTag(t *testing.T) {
|
||||
_, err := GenerateClass("invalid", "C")
|
||||
assert.Error(t, err, "custom element names must contain a hyphen")
|
||||
}
|
||||
|
||||
func TestGenerateRegistration_Good(t *testing.T) {
|
||||
func TestGenerateRegistration_DefinesCustomElement(t *testing.T) {
|
||||
js := GenerateRegistration("photo-grid", "PhotoGrid")
|
||||
assert.Contains(t, js, "customElements.define")
|
||||
assert.Contains(t, js, `"photo-grid"`)
|
||||
assert.Contains(t, js, "PhotoGrid")
|
||||
}
|
||||
|
||||
func TestTagToClassName_Good(t *testing.T) {
|
||||
func TestTagToClassName_KebabCase(t *testing.T) {
|
||||
tests := []struct{ tag, want string }{
|
||||
{"photo-grid", "PhotoGrid"},
|
||||
{"nav-breadcrumb", "NavBreadcrumb"},
|
||||
|
|
@ -41,14 +43,16 @@ func TestTagToClassName_Good(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGenerateBundle_Good(t *testing.T) {
|
||||
func TestGenerateBundle_DeduplicatesRegistrations(t *testing.T) {
|
||||
slots := map[string]string{
|
||||
"H": "nav-bar",
|
||||
"C": "main-content",
|
||||
"F": "nav-bar",
|
||||
}
|
||||
js, err := GenerateBundle(slots)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, js, "NavBar")
|
||||
assert.Contains(t, js, "MainContent")
|
||||
assert.Equal(t, 2, strings.Count(js, "extends HTMLElement"))
|
||||
assert.Equal(t, 2, strings.Count(js, "customElements.define"))
|
||||
}
|
||||
|
|
|
|||
13
codegen/doc.go
Normal file
13
codegen/doc.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//go:build !js
|
||||
|
||||
// SPDX-Licence-Identifier: EUPL-1.2
|
||||
|
||||
// Package codegen generates Web Component bundles for go-html slot maps.
|
||||
//
|
||||
// Use it at build time, or through the cmd/codegen CLI:
|
||||
//
|
||||
// bundle, err := GenerateBundle(map[string]string{
|
||||
// "H": "site-header",
|
||||
// "C": "app-main",
|
||||
// })
|
||||
package codegen
|
||||
12
doc.go
Normal file
12
doc.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-Licence-Identifier: EUPL-1.2
|
||||
|
||||
// Package html renders semantic HTML from composable node trees.
|
||||
//
|
||||
// A typical page combines Layout, El, Text, and Render:
|
||||
//
|
||||
// page := NewLayout("HCF").
|
||||
// H(El("h1", Text("page.title"))).
|
||||
// C(El("main", Text("page.body"))).
|
||||
// F(El("small", Text("page.footer")))
|
||||
// out := Render(page, NewContext())
|
||||
package html
|
||||
|
|
@ -66,7 +66,7 @@ go test ./cmd/codegen/
|
|||
go test ./cmd/wasm/
|
||||
```
|
||||
|
||||
The WASM size gate test (`TestWASMBinarySize_Good`) builds the WASM binary as a subprocess. It is slow and is skipped under `-short`. It is also guarded with `//go:build !js` so it cannot run within the WASM environment itself.
|
||||
The WASM size gate test (`TestWASMBinarySize_WithinBudget`) builds the WASM binary as a subprocess. It is slow and is skipped under `-short`. It is also guarded with `//go:build !js` so it cannot run within the WASM environment itself.
|
||||
|
||||
### Test Dependencies
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ func TestIntegration_RenderThenReverse(t *testing.T) {
|
|||
### Codegen Tests with Testify
|
||||
|
||||
```go
|
||||
func TestGenerateClass_Good(t *testing.T) {
|
||||
func TestGenerateClass_ValidTag(t *testing.T) {
|
||||
js, err := GenerateClass("photo-grid", "C")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, js, "class PhotoGrid extends HTMLElement")
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ The fix was applied in three distinct steps:
|
|||
|
||||
### Size gate test (`aae5d21`)
|
||||
|
||||
`cmd/wasm/size_test.go` was added to prevent regression. `TestWASMBinarySize_Good` builds the WASM binary in a temp directory, gzip-compresses it, and asserts:
|
||||
`cmd/wasm/size_test.go` was added to prevent regression. `TestWASMBinarySize_WithinBudget` builds the WASM binary in a temp directory, gzip-compresses it, and asserts:
|
||||
|
||||
- Gzip size < 1,048,576 bytes (1 MB).
|
||||
- Raw size < 3,145,728 bytes (3 MB).
|
||||
|
|
|
|||
10
edge_test.go
10
edge_test.go
|
|
@ -1,7 +1,7 @@
|
|||
package html
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ func TestLayout_DeepNesting_10Levels(t *testing.T) {
|
|||
for i := 1; i < 10; i++ {
|
||||
expectedBlock += "-C-0"
|
||||
}
|
||||
if !strings.Contains(got, fmt.Sprintf(`data-block="%s"`, expectedBlock)) {
|
||||
if !strings.Contains(got, `data-block="`+expectedBlock+`"`) {
|
||||
t.Errorf("10 levels deep: missing expected block ID %q in:\n%s", expectedBlock, got)
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ func TestEach_LargeIteration_1000(t *testing.T) {
|
|||
}
|
||||
|
||||
node := Each(items, func(i int) Node {
|
||||
return El("li", Raw(fmt.Sprintf("%d", i)))
|
||||
return El("li", Raw(strconv.Itoa(i)))
|
||||
})
|
||||
|
||||
got := node.Render(ctx)
|
||||
|
|
@ -275,7 +275,7 @@ func TestEach_LargeIteration_5000(t *testing.T) {
|
|||
}
|
||||
|
||||
node := Each(items, func(i int) Node {
|
||||
return El("span", Raw(fmt.Sprintf("%d", i)))
|
||||
return El("span", Raw(strconv.Itoa(i)))
|
||||
})
|
||||
|
||||
got := node.Render(ctx)
|
||||
|
|
@ -292,7 +292,7 @@ func TestEach_NestedEach(t *testing.T) {
|
|||
|
||||
node := Each(rows, func(row int) Node {
|
||||
return El("tr", Each(cols, func(col string) Node {
|
||||
return El("td", Raw(fmt.Sprintf("%d-%s", row, col)))
|
||||
return El("td", Raw(strconv.Itoa(row)+"-"+col))
|
||||
}))
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue