179 lines
3.9 KiB
Go
179 lines
3.9 KiB
Go
//go:build !js
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
goio "io"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
core "dappco.re/go/core"
|
|
coreio "dappco.re/go/core/io"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRun_WritesBundle_Good(t *testing.T) {
|
|
input := core.NewReader(`{"H":"nav-bar","C":"main-content"}`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, false)
|
|
require.NoError(t, err)
|
|
|
|
js := output.String()
|
|
assert.Contains(t, js, "NavBar")
|
|
assert.Contains(t, js, "MainContent")
|
|
assert.Contains(t, js, "customElements.define")
|
|
assert.Equal(t, 2, countSubstr(js, "extends HTMLElement"))
|
|
}
|
|
|
|
func TestRun_InvalidJSON_Bad(t *testing.T) {
|
|
input := core.NewReader(`not json`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, false)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "invalid JSON")
|
|
}
|
|
|
|
func TestRun_InvalidTag_Bad(t *testing.T) {
|
|
input := core.NewReader(`{"H":"notag"}`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, false)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "hyphen")
|
|
}
|
|
|
|
func TestRun_InvalidTagCharacters_Bad(t *testing.T) {
|
|
input := core.NewReader(`{"H":"Nav-Bar","C":"nav bar"}`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, false)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.Error(), "lowercase hyphenated name")
|
|
}
|
|
|
|
func TestRun_EmptySlots_Good(t *testing.T) {
|
|
input := core.NewReader(`{}`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, false)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, output.String())
|
|
}
|
|
|
|
func TestRun_WritesTypeScriptDefinitions_Good(t *testing.T) {
|
|
input := core.NewReader(`{"H":"nav-bar","C":"main-content"}`)
|
|
output := core.NewBuilder()
|
|
|
|
err := run(input, output, true)
|
|
require.NoError(t, err)
|
|
|
|
dts := output.String()
|
|
assert.Contains(t, dts, "declare global")
|
|
assert.Contains(t, dts, `"nav-bar": NavBar;`)
|
|
assert.Contains(t, dts, `"main-content": MainContent;`)
|
|
assert.Contains(t, dts, "export declare class NavBar extends HTMLElement")
|
|
assert.Contains(t, dts, "export declare class MainContent extends HTMLElement")
|
|
}
|
|
|
|
func TestRunDaemon_WritesUpdatedBundle_Good(t *testing.T) {
|
|
dir := t.TempDir()
|
|
inputPath := filepath.Join(dir, "slots.json")
|
|
outputPath := filepath.Join(dir, "bundle.js")
|
|
|
|
require.NoError(t, writeTextFile(inputPath, `{"H":"nav-bar","C":"main-content"}`))
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
done <- runDaemon(ctx, inputPath, outputPath, false, 5*time.Millisecond)
|
|
}()
|
|
|
|
require.Eventually(t, func() bool {
|
|
got, err := readTextFile(outputPath)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return strings.Contains(got, "NavBar") && strings.Contains(got, "MainContent")
|
|
}, time.Second, 10*time.Millisecond)
|
|
|
|
cancel()
|
|
require.NoError(t, <-done)
|
|
}
|
|
|
|
func TestRunDaemon_MissingPaths_Bad(t *testing.T) {
|
|
err := runDaemon(context.Background(), "", "", false, time.Millisecond)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "watch mode requires -input")
|
|
}
|
|
|
|
func countSubstr(s, substr string) int {
|
|
if substr == "" {
|
|
return len(s) + 1
|
|
}
|
|
|
|
count := 0
|
|
for i := 0; i <= len(s)-len(substr); {
|
|
j := indexSubstr(s[i:], substr)
|
|
if j < 0 {
|
|
return count
|
|
}
|
|
count++
|
|
i += j + len(substr)
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func indexSubstr(s, substr string) int {
|
|
if substr == "" {
|
|
return 0
|
|
}
|
|
if len(substr) > len(s) {
|
|
return -1
|
|
}
|
|
|
|
for i := 0; i <= len(s)-len(substr); i++ {
|
|
if s[i:i+len(substr)] == substr {
|
|
return i
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
func writeTextFile(path, content string) error {
|
|
f, err := coreio.Local.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
_ = f.Close()
|
|
}()
|
|
|
|
_, err = goio.WriteString(f, content)
|
|
return err
|
|
}
|
|
|
|
func readTextFile(path string) (string, error) {
|
|
f, err := coreio.Local.Open(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer func() {
|
|
_ = f.Close()
|
|
}()
|
|
|
|
data, err := goio.ReadAll(f)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(data), nil
|
|
}
|