Skip to content

Commit 6d91ec0

Browse files
author
Nathan Gillett
committed
ci(sdk-go): enforce 95% coverage on intentproof package
Rebase coverage gate onto merged core SDK: JCS tests in jcs.go, weighted coverage script, expanded internal tests, and preserved go-sdk-core hardening (configure lock, export flush, wrap logging). Signed-off-by: Nathan Gillett <nathan@intentproof.io>
1 parent d412879 commit 6d91ec0

27 files changed

Lines changed: 1828 additions & 111 deletions

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ jobs:
2020
- name: Verify module metadata
2121
run: go mod verify
2222

23-
- name: Run tests
24-
run: go test ./...
23+
- name: Run tests and enforce coverage
24+
run: bash ./scripts/check-coverage.sh 95

.github/workflows/release-signing-dry-run.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ jobs:
3434
- name: Verify module metadata
3535
run: go mod verify
3636

37-
- name: Run tests
38-
run: go test ./...
37+
- name: Run tests with coverage
38+
run: bash ./scripts/check-coverage.sh 95
3939

4040
- name: Package module source archive
4141
run: |

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
*.out
1111
coverage.out
1212
coverage.html
13+
*.db
14+
*.db-shm
15+
*.db-wal
16+
intentproof/outbox
17+
intentproof/outbox-*
1318

1419
# Build output
1520
/bin/

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,14 @@ Default signing keys live under `~/.intentproof/sdk-go/keypair.json`.
6969

7070
```bash
7171
go test ./...
72+
bash ./scripts/check-coverage.sh 95
7273
```
7374

75+
CI enforces at least 95% line coverage on the `intentproof/` package (see
76+
`scripts/check-coverage.sh`). The vendored RFC 8785 engine in `jcs.go` is
77+
validated by conformance vectors in `jcs_test.go` and is excluded from that
78+
line threshold.
79+
7480
Cross-language signing fixtures under `testdata/fixtures/` match the Node and
7581
Python SDK conformance set.
7682

intentproof/canon.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package intentproof
22

3-
import (
4-
"github.com/intentproof/intentproof-sdk-go/internal/canon"
5-
)
6-
73
// Canonicalize returns the RFC 8785 canonical JSON encoding of v.
84
func Canonicalize(v any) (string, error) {
9-
b, err := canon.Marshal(v)
5+
b, err := marshalJCS(v)
106
if err != nil {
117
return "", err
128
}

intentproof/client.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ var (
2929
exporter *HTTPExporter
3030
)
3131

32+
var userHomeDirFn = os.UserHomeDir
33+
3234
// DefaultDataDir returns the default SDK data directory.
3335
func DefaultDataDir() string {
34-
home, err := os.UserHomeDir()
36+
home, err := userHomeDirFn()
3537
if err != nil {
3638
return filepath.Join(".intentproof", "sdk-go")
3739
}

intentproof/client_extra_test.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package intentproof_test
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/intentproof/intentproof-sdk-go/intentproof"
9+
)
10+
11+
func TestDefaultDataDir(t *testing.T) {
12+
dir := intentproof.DefaultDataDir()
13+
if dir == "" {
14+
t.Fatal("expected non-empty default data dir")
15+
}
16+
}
17+
18+
func TestGettersBeforeConfigure(t *testing.T) {
19+
// Reset state by configuring then we need isolated package - instead test error paths
20+
// by using a fresh module is hard; test GetTenantID without configure returns default.
21+
if intentproof.GetTenantID() == "" {
22+
t.Fatal("expected default tenant")
23+
}
24+
}
25+
26+
func TestConfigureUsesDefaultDataDirWhenOmitted(t *testing.T) {
27+
dir := t.TempDir()
28+
os.Unsetenv("INTENTPROOF_OUTBOX_PATH")
29+
if err := intentproof.Configure(intentproof.ConfigureOptions{
30+
DBPath: filepath.Join(dir, "outbox.db"),
31+
TenantID: "tnt_default_dir",
32+
}); err != nil {
33+
t.Fatal(err)
34+
}
35+
}
36+
37+
func TestConfigureWithEnvTenantAndOutboxPath(t *testing.T) {
38+
dir := t.TempDir()
39+
t.Setenv("INTENTPROOF_TENANT_ID", "tnt_from_env")
40+
t.Setenv("INTENTPROOF_OUTBOX_PATH", filepath.Join(dir, "custom.db"))
41+
if err := intentproof.Configure(intentproof.ConfigureOptions{
42+
DataDir: filepath.Join(dir, "data"),
43+
}); err != nil {
44+
t.Fatal(err)
45+
}
46+
if intentproof.GetTenantID() != "tnt_from_env" {
47+
t.Fatalf("tenant: %s", intentproof.GetTenantID())
48+
}
49+
}
50+
51+
func TestConfigureInvalidKeypairFails(t *testing.T) {
52+
dir := t.TempDir()
53+
dataDir := filepath.Join(dir, "data")
54+
if err := os.MkdirAll(dataDir, 0o700); err != nil {
55+
t.Fatal(err)
56+
}
57+
if err := os.WriteFile(filepath.Join(dataDir, "keypair.json"), []byte("not-json"), 0o600); err != nil {
58+
t.Fatal(err)
59+
}
60+
dbPath, _ := testDirs(t)
61+
err := intentproof.Configure(intentproof.ConfigureOptions{
62+
DBPath: dbPath,
63+
DataDir: dataDir,
64+
TenantID: "tnt_bad",
65+
})
66+
if err == nil {
67+
t.Fatal("expected configure error")
68+
}
69+
}
70+
71+
func TestFlushWithoutExporter(t *testing.T) {
72+
dbPath, dataDir := testDirs(t)
73+
configureTest(t, dbPath, dataDir, "tnt_a")
74+
intentproof.Flush() // no exporter configured
75+
}
76+
77+
func TestPushSubjectMappingNoOp(t *testing.T) {
78+
intentproof.PushSubjectMapping("src", "type", "id")
79+
}
80+
81+
func TestWrapGeneratesCorrelationIDWhenUnset(t *testing.T) {
82+
dbPath, dataDir := testDirs(t)
83+
configureTest(t, dbPath, dataDir, "tnt_auto_corr")
84+
fn := intentproof.Wrap("Test", "test.action", func(x int) int { return x })
85+
fn(1)
86+
ob, _ := intentproof.GetOutbox()
87+
events, _ := ob.Events()
88+
if len(events) != 1 {
89+
t.Fatalf("events: %d", len(events))
90+
}
91+
cid, _ := events[0]["correlation_id"].(string)
92+
if cid == "" || cid == "corr-outer" {
93+
// should be req_* ULID, not empty or from other tests' fixed ids
94+
if len(cid) < 4 || cid[:4] != "req_" {
95+
t.Fatalf("correlation_id: %q", cid)
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)