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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
vars {
number $x = 10 + 1
}

send [USD/2 10] (
source = @world
destination = @alice
)

set_tx_meta("key", $x/2)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"featureFlags": [
"experimental-overdraft-function",
"experimental-mid-script-function-call",
"experimental-oneof"
],
"testCases": [
{
"it": "sets the expected meta",
"expect.txMetadata": {
"key": "11/2"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
vars {
number $amt
}

send [USD $amt] (
source = oneof {
@s1
@s2
{
@s1
@s2
}
}
destination = @dest
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"variables": {
"amt": "10"
},
"featureFlags": ["experimental-oneof"],
"testCases": [
{
"it": "sends from the first source when there is enough balance",
"balances": {
"s1": {
"USD": 999
}
},
"expect.postings": [
{
"source": "s1",
"destination": "dest",
"amount": 10,
"asset": "USD"
}
]
},
{
"it": "sends from the second one when it has enough balance but the first one doesn't",
"balances": {
"s1": {
"USD": 9
},
"s2": {
"USD": 999
}
},
"expect.postings": [
{
"source": "s2",
"destination": "dest",
"amount": 10,
"asset": "USD"
}
]
},
{
"it": "sends partially from both when none of them has enough balance on its own",
"balances": {
"s1": {
"USD": 6
},
"s2": {
"USD": 9
}
},
"expect.postings": [
{
"source": "s1",
"destination": "dest",
"amount": 6,
"asset": "USD"
},
{
"source": "s2",
"destination": "dest",
"amount": 4,
"asset": "USD"
}
]
},
{
"it": "fails if there aren't enough funds between all sources",
"balances": {
"s1": {
"USD": 5
},
"s2": {
"USD": 4
}
},
"expect.missingFunds": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
vars {
number $amt
}
Comment on lines +1 to +3
Copy link
Contributor

@coderabbitai coderabbitai bot Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Uninitialized variable will cause runtime error.

The variable $amt is declared but never initialized. This will likely cause a runtime error when the script attempts to execute the send operation.

Add an initialization value to fix this issue:

 vars {
-  number $amt
+  number $amt = 100
 }

Or specify the amount directly in the send operation and remove the variable if it's meant to be a parameter.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vars {
number $amt
}
vars {
number $amt = 100
}
🤖 Prompt for AI Agents
In internal/interpreter/testdata/numscript-cookbook/experimental/top-up-many.num
at lines 1 to 3, the variable $amt is declared but not initialized, which will
cause a runtime error. Fix this by either assigning an initial value to $amt in
the vars block or by removing the variable and specifying the amount directly in
the send operation if $amt is intended as a parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ascandone Got it! I understand that the uninitialized variable is intentional for this example.

🐰
╭─────╮
│ ◕ ◕ │ curious about NumScript behavior
╰─────╯


✏️ Learnings added
Learnt from: ascandone
PR: formancehq/numscript#88
File: internal/interpreter/testdata/numscript-cookbook/experimental/top-up-many.num:1-3
Timestamp: 2025-07-25T08:12:46.359Z
Learning: In NumScript test data files under internal/interpreter/testdata/numscript-cookbook/, variables can be declared without initialization as they may be intended as parameters or templates where values are supplied externally at runtime.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.



send [EUR $amt] (
source = @world
destination = oneof {
max overdraft(@alice, EUR) to @alice
max overdraft(@bob, EUR) to @bob
remaining kept
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"featureFlags": [
"experimental-overdraft-function",
"experimental-mid-script-function-call",
"experimental-oneof"
],
"variables": {
"amt": "100"
},
"testCases": [
{
"it": "should be a noop when all balances are >= 0",
"balances": { "alice": { "EUR": 100 }, "bob": { "EUR": 200 } },
"expect.postings": []
},
{
"it": "should prioritize alice when both have missing funds",
"balances": {
"alice": { "EUR": -120 },
"bob": { "EUR": -120 }
},
"expect.postings": [
{
"source": "world",
"destination": "alice",
"amount": 100,
"asset": "EUR"
}
]
},
{
"it": "doesn't send funds to alice if there aren't enough funds for the account to be topped-up",
"balances": {
"alice": { "EUR": -80 },
"bob": { "EUR": -120 }
},
"expect.postings": [
{
"source": "world",
"destination": "bob",
"amount": 100,
"asset": "EUR"
}
]
},
{
"it": "funds are kept if there are spare funds",
"balances": {
"alice": { "EUR": -10 },
"bob": { "EUR": -20 }
},
"expect.postings": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
vars {
monetary $alice_overdraft = overdraft(@alice, EUR)
}

send $alice_overdraft (
source = @world
destination = @alice
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"featureFlags": ["experimental-overdraft-function"],
"testCases": [
{
"it": "should not emit postings",
"balances": { "alice": { "EUR": 100 } },
"expect.postings": []
},
{
"it": "should send the missing amount to an overdraft account",
"balances": { "alice": { "EUR": -100 } },
"expect.volumes": {
"alice": { "EUR": 0 },
"world": { "EUR": -100 }
},
"expect.movements": {
"world": {
"alice": { "EUR": 100 }
}
},
"expect.postings": [
{
"source": "world",
"destination": "alice",
"amount": 100,
"asset": "EUR"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
vars {
number $amt
account $dest
monetary $bank_overdraft = overdraft(@bank_account, EUR)
}

send [EUR $amt] (
source = max $bank_overdraft from @wallet
destination = $dest
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"featureFlags": [
"experimental-overdraft-function",
"experimental-mid-script-function-call",
"experimental-oneof"
],
"variables": {
"amt": "100",
"dest": "alice"
},
"testCases": [
{
"it": "should authorize transfer if both wallet and bank accounts display enough balance",
"balances": {
"wallet": { "EUR": 100 },
"bank_account": { "EUR": -100 }
},
"expect.postings": [
{
"source": "wallet",
"destination": "alice",
"amount": 100,
"asset": "EUR"
}
]
},
{
"it": "should not authorize transfer if wallet does not display enough balance and bank account does",
"balances": {
"wallet": { "EUR": 50 },
"bank_account": { "EUR": -100 }
},
"expect.missingFunds": true
},
{
"it": "should not authorize transfer if bank account does not display enough balance and wallet does",
"balances": {
"wallet": { "EUR": 100 },
"bank_account": { "EUR": -50 }
},
"expect.missingFunds": true
}
]
}
16 changes: 16 additions & 0 deletions internal/interpreter/testdata/numscript-cookbook/max-fee.num
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
vars {
number $amt
number $cap
portion $fee
}

send [USD $amt] (
source = @world
destination = {
$fee to {
max [USD $cap] to @fees
remaining to @dest
}
remaining to @dest
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"$schema": "https://raw.githubusercontent.com/formancehq/numscript/main/specs.schema.json",
"variables": {
"cap": "10",
"fee": "10%"
},
"testCases": [
{
"it": "it sends 10% of the fee when lower than cap",
"variables": {
"amt": "10"
},
"expect.postings": [
{
"source": "world",
"destination": "fees",
"amount": 1,
"asset": "USD"
},
{
"source": "world",
"destination": "dest",
"amount": 9,
"asset": "USD"
}
]
},
{
"it": "it caps the fee to the $cap",
"variables": {
"amt": "500"
},
"expect.postings": [
{
"source": "world",
"destination": "fees",
"amount": 10,
"asset": "USD"
},
{
"source": "world",
"destination": "dest",
"amount": 40,
"asset": "USD"
},
{
"source": "world",
"destination": "dest",
"amount": 450,
"asset": "USD"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
send [USD 77] (
source = {
10% from @src1
20% from @src2
remaining from @world
}
destination = {
1/2 to @dest1
1/2 to @dest2
}
)
Loading
Loading