diff --git a/internal/interpreter/interpreter.go b/internal/interpreter/interpreter.go index d9a6730..b04a581 100644 --- a/internal/interpreter/interpreter.go +++ b/internal/interpreter/interpreter.go @@ -177,6 +177,10 @@ func (s *programState) parseVars(varDeclrs []parser.VarDeclaration, rawVars map[ return nil } +type FeatureFlag = string + +const ExperimentalOverdraftFunctionFeatureFlag FeatureFlag = "experimental-overdraft-function" + func RunProgram( ctx context.Context, program parser.Program, @@ -196,6 +200,10 @@ func RunProgram( ctx: ctx, } + if _, ok := featureFlags[ExperimentalOverdraftFunctionFeatureFlag]; ok { + st.OverdraftFunctionFeatureFlag = true + } + err := st.parseVars(program.Vars, vars) if err != nil { return nil, err @@ -252,6 +260,8 @@ type programState struct { CachedBalances Balances CurrentBalanceQuery BalanceQuery + + OverdraftFunctionFeatureFlag bool } func (st *programState) runStatement(statement parser.Statement) ([]Posting, InterpreterError) { diff --git a/internal/interpreter/interpreter_error.go b/internal/interpreter/interpreter_error.go index 168df11..c819f1a 100644 --- a/internal/interpreter/interpreter_error.go +++ b/internal/interpreter/interpreter_error.go @@ -184,3 +184,12 @@ type QueryMetadataError struct { func (e QueryMetadataError) Error() string { return e.WrappedError.Error() } + +type ExperimentalFeature struct { + parser.Range + FlagName string +} + +func (e ExperimentalFeature) Error() string { + return fmt.Sprintf("this feature is experimental. You need the '%s' feature flag to enable it", e.FlagName) +} diff --git a/internal/interpreter/interpreter_test.go b/internal/interpreter/interpreter_test.go index 14762db..4508e0c 100644 --- a/internal/interpreter/interpreter_test.go +++ b/internal/interpreter/interpreter_test.go @@ -82,16 +82,50 @@ func (c *TestCase) setBalance(account string, asset string, amount int64) { } func test(t *testing.T, testCase TestCase) { + testWithFeatureFlag(t, testCase, "") +} + +// A version of test() which tests code under a feature flag +// if the feature flag is the empty string, it behaves as test() +// otherwise, it tests the program under that feature flag and also tests that +// the same script, without the flag, yields the ExperimentalFeature{} error +func testWithFeatureFlag(t *testing.T, testCase TestCase, flagName string) { t.Parallel() prog := testCase.program require.NotNil(t, prog) - execResult, err := machine.RunProgram(context.Background(), *prog, testCase.vars, machine.StaticStore{ - testCase.balances, - testCase.meta, - }, nil) + featureFlags := map[string]struct{}{} + if flagName != "" { + featureFlags[flagName] = struct{}{} + + _, err := machine.RunProgram( + context.Background(), + *prog, + testCase.vars, + machine.StaticStore{ + testCase.balances, + testCase.meta, + }, + nil, + ) + + require.Equal(t, machine.ExperimentalFeature{ + FlagName: flagName, + }, removeRange(err)) + } + + execResult, err := machine.RunProgram( + context.Background(), + *prog, + testCase.vars, + machine.StaticStore{ + testCase.balances, + testCase.meta, + }, + featureFlags, + ) expected := testCase.expected if expected.Error != nil { @@ -3207,7 +3241,6 @@ func TestSaveFromAccount(t *testing.T) { }) } -// new semantics func TestOverdraftFunctionWhenNegative(t *testing.T) { script := ` vars { monetary $amt = overdraft(@acc, EUR/2) } @@ -3234,7 +3267,7 @@ func TestOverdraftFunctionWhenNegative(t *testing.T) { }, Error: nil, } - test(t, tc) + testWithFeatureFlag(t, tc, machine.ExperimentalOverdraftFunctionFeatureFlag) } func TestOverdraftFunctionWhenZero(t *testing.T) { @@ -3257,7 +3290,7 @@ func TestOverdraftFunctionWhenZero(t *testing.T) { }, Error: nil, } - test(t, tc) + testWithFeatureFlag(t, tc, machine.ExperimentalOverdraftFunctionFeatureFlag) } func TestOverdraftFunctionWhenPositive(t *testing.T) { @@ -3281,7 +3314,7 @@ func TestOverdraftFunctionWhenPositive(t *testing.T) { }, Error: nil, } - test(t, tc) + testWithFeatureFlag(t, tc, machine.ExperimentalOverdraftFunctionFeatureFlag) } func TestOverdraftFunctionUseCaseRemoveDebt(t *testing.T) { @@ -3316,5 +3349,5 @@ func TestOverdraftFunctionUseCaseRemoveDebt(t *testing.T) { }, Error: nil, } - test(t, tc) + testWithFeatureFlag(t, tc, machine.ExperimentalOverdraftFunctionFeatureFlag) }