Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions sdk/tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Test output files
**/**/norm*.txt
**/**/testOutput.txt

# Test output directory created on failures
testdata/

# Go test binary
*.test

# Go build output
test-runner
compare-sse

# sdk tests
.docker-build-timestamp
142 changes: 142 additions & 0 deletions sdk/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Datastar SDK Test Suite

A comprehensive test suite for validating Datastar SDK implementations across different languages.

## Installation

### As a Go Library

```bash
go get github.com/starfederation/datastar/sdk/tests
```

## Usage

### Running Tests

```bash
# Run all tests against default server (localhost:7331)
go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest

# Run with custom server
go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest -server http://localhost:8080

# Run only GET tests
go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest -type get

# Run only POST tests
go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest -type post

# Verbose output
go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest -v
```

### Using go test directly

```bash
# Clone the repository and navigate to tests directory
cd sdk/tests

# Run all tests
go test -v

# Run with custom server
TEST_SERVER_URL=http://localhost:8080 go test -v
```

## Test Structure

The test suite includes:

- **GET Tests** (`golden/get/`): Test cases for GET endpoints
- **POST Tests** (`golden/post/`): Test cases for POST endpoints

Each test case contains:
- `input.json`: The request payload
- `output.txt`: The expected SSE response

## Features

- **HTML Normalization**: Automatically handles HTML attribute ordering differences
- **Embedded Test Data**: All test cases are embedded in the binary for portability
- **Flexible Runner**: Can be used as a CLI tool or Go library
- **Detailed Output**: Clear error messages and debug information

## For SDK Implementers

To validate your SDK implementation:

1. Start your test server on port 7331 (or specify a different port)
2. Implement the `/test` endpoint that:
- For GET: reads the `datastar` query parameter
- For POST: reads the JSON body
- Returns appropriate SSE responses
3. Run `go run github.com/starfederation/datastar/sdk/tests/cmd/datastar-sdk-tests@latest` to validate your implementation

## Test Endpoint Requirements

The `/test` endpoint should:

1. Use ReadSignals to extract the `events` array from the request
2. Loop through the array of events
3. Use `event.type` to decide which server sent event to generate
4. Return the appropriate SSE response

### Input Format

```json
{
"events": [
{
"type": "executeScript",
"script": "console.log('hello');",
"eventId": "event1",
"retryDuration": 2000,
"attributes": {
"type": "text/javascript",
"blocking": "false"
},
"autoRemove": false
}
]
}
```

### Output Format

```
event: datastar-patch-elements
id: event1
retry: 2000
data: mode append
data: selector body
data: elements <script type="text/javascript" blocking="false">console.log('hello');</script>

```

## Adding New Test Cases

To add a new test case:

1. Create a folder in `golden/get/` or `golden/post/` named after your test
2. Add an `input.json` file with the request payload
3. Add an `output.txt` file with the expected SSE response

### Special Cases

#### Multiline Signals

For `patchSignals` events, if you need multiline output:
- Use `signals-raw` as a string with `\n` characters instead of `signals` as a JSON object
- The server should check for `signals-raw` first, then fall back to `signals`

## Test Cases

The test suite covers:

- Element patching (single and multiline)
- Signal patching
- Script execution
- Element/signal removal
- Various SSE formatting scenarios
- Edge cases and error conditions
75 changes: 75 additions & 0 deletions sdk/tests/cmd/datastar-sdk-tests/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"flag"
"fmt"
"os"
"testing"

sdktests "github.com/starfederation/datastar/sdk/tests"
)

func main() {
var (
verbose = flag.Bool("v", false, "Verbose output")
testType = flag.String("type", "all", "Test type: get, post, or all")
help = flag.Bool("h", false, "Show help")
)
flag.Parse()

if *help {
fmt.Println("datastar-sdk-tests - Datastar SDK test suite")
fmt.Println("\nUsage:")
fmt.Println(" datastar-sdk-tests [options]")
fmt.Println("\nOptions:")
flag.PrintDefaults()
fmt.Println("\nExamples:")
fmt.Println(" datastar-sdk-tests # Run all tests")
fmt.Println(" datastar-sdk-tests -type get # Run only GET tests")
fmt.Println(" datastar-sdk-tests -server http://localhost:8080")
os.Exit(0)
}

// Create a testing.M to run tests
var tests []testing.InternalTest

switch *testType {
case "get":
tests = append(tests, testing.InternalTest{
Name: "TestSSEGetEndpoints",
F: sdktests.TestSSEGetEndpoints,
})
case "post":
tests = append(tests, testing.InternalTest{
Name: "TestSSEPostEndpoints",
F: sdktests.TestSSEPostEndpoints,
})
case "all":
tests = append(tests,
testing.InternalTest{
Name: "TestSSEGetEndpoints",
F: sdktests.TestSSEGetEndpoints,
},
testing.InternalTest{
Name: "TestSSEPostEndpoints",
F: sdktests.TestSSEPostEndpoints,
},
)
default:
fmt.Fprintf(os.Stderr, "Unknown test type: %s\n", *testType)
os.Exit(1)
}

// Set verbose flag if requested
if *verbose {
os.Args = append(os.Args, "-test.v")
}

// Run tests using testing.Main
testing.Main(
func(pat, str string) (bool, error) { return true, nil }, // matchString
tests, // tests
nil, // benchmarks
nil, // examples
)
}
14 changes: 14 additions & 0 deletions sdk/tests/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/starfederation/datastar/sdk/tests

go 1.21

require (
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.19.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 12 additions & 0 deletions sdk/tests/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
15 changes: 15 additions & 0 deletions sdk/tests/golden/get/executeScriptWithAllOptions/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"events": [
{
"type": "executeScript",
"script": "console.log('hello');",
"eventId": "event1",
"retryDuration": 2000,
"attributes": {
"type": "text/javascript",
"blocking": "false"
},
"autoRemove": false
}
]
}
7 changes: 7 additions & 0 deletions sdk/tests/golden/get/executeScriptWithAllOptions/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
event: datastar-patch-elements
id: event1
retry: 2000
data: mode append
data: selector body
data: elements <script type="text/javascript" blocking="false">console.log('hello');</script>

9 changes: 9 additions & 0 deletions sdk/tests/golden/get/executeScriptWithDefaults/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"events": [
{
"type": "executeScript",
"script": "console.log('hello');",
"autoRemove": true
}
]
}
5 changes: 5 additions & 0 deletions sdk/tests/golden/get/executeScriptWithDefaults/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
event: datastar-patch-elements
data: mode append
data: selector body
data: elements <script data-effect="el.remove()">console.log('hello');</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"events": [
{
"type": "executeScript",
"script": "if (true) {\n console.log('hello');\n}"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
event: datastar-patch-elements
data: mode append
data: selector body
data: elements <script data-effect="el.remove()">if (true) {
data: elements console.log('hello');
data: elements }</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"events": [
{
"type": "executeScript",
"script": "console.log('hello');"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
event: datastar-patch-elements
data: mode append
data: selector body
data: elements <script data-effect="el.remove()">console.log('hello');</script>

13 changes: 13 additions & 0 deletions sdk/tests/golden/get/patchElementsWithAllOptions/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"events": [
{
"type": "patchElements",
"elements": "<div>Merge</div>",
"eventId": "event1",
"retryDuration": 2000,
"selector": "div",
"mode": "append",
"useViewTransition": true
}
]
}
8 changes: 8 additions & 0 deletions sdk/tests/golden/get/patchElementsWithAllOptions/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
event: datastar-patch-elements
id: event1
retry: 2000
data: selector div
data: mode append
data: useViewTransition true
data: elements <div>Merge</div>

10 changes: 10 additions & 0 deletions sdk/tests/golden/get/patchElementsWithDefaults/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"events": [
{
"type": "patchElements",
"elements": "<div>Merge</div>",
"mode": "outer",
"useViewTransition": false
}
]
}
3 changes: 3 additions & 0 deletions sdk/tests/golden/get/patchElementsWithDefaults/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
event: datastar-patch-elements
data: elements <div>Merge</div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"events": [
{
"type": "patchElements",
"elements": "<div>\n <span>Merge</span>\n</div>"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
event: datastar-patch-elements
data: elements <div>
data: elements <span>Merge</span>
data: elements </div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"events": [
{
"type": "patchElements",
"elements": "<div>Merge</div>"
}
]
}
Loading