Files
numscript/internal/specs_format/runner_test.go
Alessandro ScandoneandGitHub 3a4eb3803f feat: improve testing tool (#93)
* breaking: change assertion name

* feat: add errMissingFunds assertion

* breaking: renamed assertion

* breaking: renamed assertions

* feat: added expect.endBalances.include assertion

* feat: better test output

* fix

* feat: added focus and skip

* improve UI for focused/skipped tests

* improve test ui
2025-10-02 16:29:35 +02:00

259 lines
5.0 KiB
Go

package specs_format_test
import (
"bytes"
"testing"
"github.com/formancehq/numscript/internal/specs_format"
"github.com/gkampitakis/go-snaps/snaps"
"github.com/stretchr/testify/require"
)
func TestShowDiff(t *testing.T) {
var buf bytes.Buffer
specs_format.ShowDiff(
&buf,
map[string]any{
"common": "ok",
"x": 42,
},
map[string]any{
"common": "ok",
"x": 100,
},
)
snaps.MatchSnapshot(t, buf.String())
}
func TestSingleTest(t *testing.T) {
var out bytes.Buffer
script := `
send [USD/2 100] (
source = @world
destination = @dest
)
`
specs := `
{
"testCases": [
{
"it": "tfailing",
"expect.postings": [{
"source": "wrong-source",
"destination": "dest",
"asset": "USD/2",
"amount": 100
}]
},
{
"it": "tpassing",
"expect.postings": [{
"source": "world",
"destination": "dest",
"asset": "USD/2",
"amount": 100
}]
}
]
}
`
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: script,
SpecsFileContent: []byte(specs),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestComplexAssertions(t *testing.T) {
var out bytes.Buffer
script := `
send [USD/2 100] (
source = @alice
destination = @dest
)
`
specs := `
{
"testCases": [
{
"it": "send when there are enough funds",
"balances": {
"alice": { "USD/2": 9999 }
},
"expect.endBalances": {
"alice": { "USD/2": -100 },
"dest": { "USD/2": 1 }
},
"expect.movements": {
"alice": {
"dest": { "EUR": 100 }
}
},
"expect.error.missingFunds": true
},
{
"it": "tpassing",
"balances": {
"alice": { "USD/2": 0 }
},
"expect.error.missingFunds": true
}
]
}
`
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: script,
SpecsFileContent: []byte(specs),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestNoFilesErr(t *testing.T) {
var out bytes.Buffer
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestParseErrSpecs(t *testing.T) {
var out bytes.Buffer
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: "",
SpecsFileContent: []byte(`
not a json
`),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestSchemaErrSpecs(t *testing.T) {
var out bytes.Buffer
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: "",
SpecsFileContent: []byte(`
{ "balances": 42 }
`),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestNumscriptParseErr(t *testing.T) {
var out bytes.Buffer
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: "!err",
SpecsFileContent: []byte(`
{ }
`),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestRuntimeErr(t *testing.T) {
var out bytes.Buffer
specs := `
{
"testCases": [
{
"it": "runs",
"expect.error.missingFunds": false
}
]
}
`
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: `send [USD/2 100] ( source = "ops!" destination = @world)`,
SpecsFileContent: []byte(specs),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}
func TestFocusUi(t *testing.T) {
specs := `{
"testCases": [
{
"it": "t1",
"variables": { "source": "src", "amount": "10" },
"balances": { "src": { "USD": 9999 } },
"expect.postings": [
{ "source": "src", "destination": "dest", "asset": "USD", "amount": 42 }
]
},
{
"it": "t2",
"focus": true,
"variables": { "source": "src", "amount": "42" },
"balances": { "src": { "USD": 9999 } },
"expect.postings": [
{ "source": "src", "destination": "dest", "asset": "USD", "amount": 42 }
]
}
]
}`
var out bytes.Buffer
success := specs_format.RunSpecs(&out, &out, []specs_format.RawSpec{
{
NumscriptPath: "example.num",
SpecsPath: "example.num.specs.json",
NumscriptContent: ` vars {
account $source
number $amount
}
send [USD $amount] (
source = $source
destination = @dest
)`,
SpecsFileContent: []byte(specs),
},
})
require.False(t, success)
snaps.MatchSnapshot(t, out.String())
}