From b379e39ce81a995812895f4aa4fe079372f76ba0 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 23 May 2026 20:29:29 +0300 Subject: style: run gofmt on all Go source files Fix formatting in 12 files to match gofmt standards. No logical changes. --- cmd/gt/main.go | 24 +++++++-------- cmd/gt/main_test.go | 40 ++++++++++++------------- integrationtests/cli_test.go | 10 +++---- internal/repl/handlers.go | 2 +- internal/repl/repl.go | 4 +-- internal/repl/repl_test.go | 56 +++++++++++++++++------------------ internal/rpn/metric_test.go | 38 ++++++++++++------------ internal/rpn/operations_hyper.go | 2 -- internal/rpn/operations_hyper_test.go | 14 ++++----- internal/rpn/operations_test.go | 9 +++--- internal/rpn/rpn_parse.go | 17 +++++------ internal/rpn/rpn_test.go | 37 +++++++++++------------ 12 files changed, 124 insertions(+), 129 deletions(-) diff --git a/cmd/gt/main.go b/cmd/gt/main.go index e01bcef..647f70f 100644 --- a/cmd/gt/main.go +++ b/cmd/gt/main.go @@ -6,14 +6,14 @@ // gt is a versatile calculator that supports both percentage calculations and // Reverse Polish Notation (RPN) expressions. It can be used in two modes: // -// 1. Command-line mode: Pass calculations as arguments -// gt 20% of 150 # Calculate 20% of 150 -// gt 3 4 + # RPN expression: 3 + 4 +// 1. Command-line mode: Pass calculations as arguments +// gt 20% of 150 # Calculate 20% of 150 +// gt 3 4 + # RPN expression: 3 + 4 // -// 2. Interactive REPL mode: Run without arguments to start an interactive session -// gt # Start interactive REPL +// 2. Interactive REPL mode: Run without arguments to start an interactive session +// gt # Start interactive REPL // -// Percentage Calculations +// # Percentage Calculations // // The calculator supports various percentage formats: // - Basic percentage: "20% of 150" → 30 @@ -21,7 +21,7 @@ // - Reverse percentage: "30 is what % of 150" → 20% // - Find base: "30 is 20% of what" → 150 // -// RPN (Reverse Polish Notation) Support +// # RPN (Reverse Polish Notation) Support // // RPN expressions use postfix notation where operators follow operands: // - Basic operations: "3 4 +" (3 + 4), "5 2 -" (5 - 2) @@ -30,12 +30,12 @@ // - Variable assignment: "x 5 = x x +" (assign x=5, then x + x) // - Stack operations: "dup swap pop show" // -// Error Handling +// # Error Handling // // Errors from calculations or parsing are printed to stdout with exit code 1. // Invalid RPN expressions and malformed percentage queries both return errors. // -// Architecture +// # Architecture // // The package uses a layered architecture: // - main.go: Entry point and command routing @@ -98,7 +98,7 @@ func runCommand(args []string) (string, error) { // Check for --log flag var logFile string var remainingArgs []string - + for i := 0; i < len(args); i++ { if args[i] == "--log" && i+1 < len(args) { logFile = args[i+1] @@ -107,10 +107,10 @@ func runCommand(args []string) (string, error) { remainingArgs = append(remainingArgs, args[i]) } } - + // Update args to exclude --log flag args = remainingArgs - + if len(args) < 2 { // No args provided - check if stdin is a TTY for REPL mode if isatty.IsTerminal(os.Stdin.Fd()) { diff --git a/cmd/gt/main_test.go b/cmd/gt/main_test.go index 9146d6d..617b741 100644 --- a/cmd/gt/main_test.go +++ b/cmd/gt/main_test.go @@ -178,32 +178,32 @@ func TestRunCommandNoArgs(t *testing.T) { // TestRunCommandAssignmentSyntaxes tests all variable assignment syntaxes func TestRunCommandAssignmentSyntaxes(t *testing.T) { tests := []struct { - name string - input string - expectedVar string - expectedVal float64 - expectedOut string + name string + input string + expectedVar string + expectedVal float64 + expectedOut string }{ { - name: "x 5 = x x + (standard assignment)", - input: "x 5 = x x +", - expectedVar: "x", - expectedVal: 5, - expectedOut: "10", + name: "x 5 = x x + (standard assignment)", + input: "x 5 = x x +", + expectedVar: "x", + expectedVal: 5, + expectedOut: "10", }, { - name: "x 5 =: x x + (left assignment)", - input: "5 x =: x x +", - expectedVar: "x", - expectedVal: 5, - expectedOut: "10", + name: "x 5 =: x x + (left assignment)", + input: "5 x =: x x +", + expectedVar: "x", + expectedVal: 5, + expectedOut: "10", }, { - name: "x 5 := x x + (right assignment)", - input: "x 5 := x x +", - expectedVar: "x", - expectedVal: 5, - expectedOut: "10", + name: "x 5 := x x + (right assignment)", + input: "x 5 := x x +", + expectedVar: "x", + expectedVal: 5, + expectedOut: "10", }, } diff --git a/integrationtests/cli_test.go b/integrationtests/cli_test.go index deded52..5567ad1 100644 --- a/integrationtests/cli_test.go +++ b/integrationtests/cli_test.go @@ -13,7 +13,7 @@ import ( // buildBinary builds the gt binary to a temporary location. func buildBinary(t *testing.T) string { t.Helper() - + // Get the project root directory projectRoot := os.Getenv("GITHUB_WORKSPACE") if projectRoot == "" { @@ -25,19 +25,19 @@ func buildBinary(t *testing.T) string { if err := buildCmd.Run(); err != nil { t.Fatalf("build failed: %v", err) } - + t.Cleanup(func() { // Explicitly ignore error return from os.Remove during cleanup _ = os.Remove("/tmp/gt-test") }) - + return "/tmp/gt-test" } // TestCLIVersion tests that the version command works correctly. func TestCLIVersion(t *testing.T) { binaryPath := buildBinary(t) - + cmd := exec.Command(binaryPath, "version") output, err := cmd.CombinedOutput() if err != nil { @@ -53,7 +53,7 @@ func TestCLIVersion(t *testing.T) { // TestCLIVersionOnly tests that the version command works correctly. func TestCLIVersionOnly(t *testing.T) { binaryPath := buildBinary(t) - + cmd := exec.Command(binaryPath, "version") output, err := cmd.CombinedOutput() if err != nil { diff --git a/internal/repl/handlers.go b/internal/repl/handlers.go index 78f07dd..f5fb909 100644 --- a/internal/repl/handlers.go +++ b/internal/repl/handlers.go @@ -193,7 +193,7 @@ func (h *RPNHandler) Handle(repl *REPL, input string) (output string, handled bo return result, true, nil } } - + // Check if input is a symbol syntax (:x) - valid RPN that pushes a symbol if len(fields) == 1 { token := fields[0] diff --git a/internal/repl/repl.go b/internal/repl/repl.go index 29314eb..01c9822 100644 --- a/internal/repl/repl.go +++ b/internal/repl/repl.go @@ -94,8 +94,8 @@ type REPL struct { // - Tab completion // - Multi-line input type ReadlinePrompt struct { - instance *readline.Instance - executor func(string) + instance *readline.Instance + executor func(string) } // NewReadlinePrompt creates a new readline-based prompt instance. diff --git a/internal/repl/repl_test.go b/internal/repl/repl_test.go index a242956..8112227 100644 --- a/internal/repl/repl_test.go +++ b/internal/repl/repl_test.go @@ -450,15 +450,15 @@ func TestExecutorWithRatModeToggle(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // First toggle defaultExecutor(rpl, "rat toggle") mode1 := rpnCalc.GetMode() - + // Second toggle defaultExecutor(rpl, "rat toggle") mode2 := rpnCalc.GetMode() - + // Modes should be different after toggle if mode1 == mode2 { t.Errorf("Modes should be different after toggle: %v -> %v", mode1, mode2) @@ -495,7 +495,7 @@ func TestExecutorWithAssignmentRight(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // Test := operator defaultExecutor(rpl, "5 x :=") val, exists := vars.GetVariable("x") @@ -505,7 +505,7 @@ func TestExecutorWithAssignmentRight(t *testing.T) { if val != 5 { t.Errorf("Variable x = %v, want 5", val) } - + // Test =: operator defaultExecutor(rpl, "y 3 =:") val, exists = vars.GetVariable("y") @@ -528,7 +528,7 @@ func TestExecutorWithAssignmentAfterCalculation(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // Test that assignment works after a calculation defaultExecutor(rpl, "1 2 + z =:") val, exists := vars.GetVariable("z") @@ -551,13 +551,13 @@ func TestExecutorWithIncrementalAssignment(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // Test that assignment works after a calculation defaultExecutor(rpl, "1 2 +") - + // Now use z =: to assign the top of stack (3) to variable z defaultExecutor(rpl, "z =:") - + val, exists := vars.GetVariable("z") if !exists { t.Errorf("Variable z should exist after z =:") @@ -578,10 +578,10 @@ func TestExecutorWithSimpleIncrementalAssignment(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // First execute 2 to put it on the stack defaultExecutor(rpl, "2") - + // Then use x =: to assign the top of stack to variable x defaultExecutor(rpl, "x =:") val, exists := vars.GetVariable("x") @@ -604,17 +604,17 @@ func TestExecutorWithExactUserScenario(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // This test replicates the exact user interaction: // > 2 // > x =: // The variable should be assigned the value 2 - + defaultExecutor(rpl, "2") - + // Verify stack has 2 // (can't directly check stack without exposing it, but next command will fail if stack is empty) - + defaultExecutor(rpl, "x =:") val, exists := vars.GetVariable("x") if !exists { @@ -636,18 +636,18 @@ func TestExecutorWithExactUserScenarioWithOutput(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // Clear any previous state defaultExecutor(rpl, "rpn clear") - + // Put 2 on stack defaultExecutor(rpl, "2") _, _ = rpnCalc.ResultStack([]string{}) - + // Assign to x =: result, err := rpnCalc.ParseAndEvaluate("x =:") t.Logf("ParseAndEvaluate('x =:') returned result=%q, err=%v", result, err) - + val, exists := vars.GetVariable("x") if !exists { t.Errorf("Variable x should exist after x =:") @@ -668,16 +668,16 @@ func TestExecutorWithExactUserScenarioDirect(t *testing.T) { commandChain: NewCommandChain(), rpnState: &RPNState{vars: vars, rpnCalc: rpnCalc}, } - + // Clear any previous state defaultExecutor(rpl, "rpn clear") - + // Simulate typing "2" in REPL defaultExecutor(rpl, "2") - + // Simulate typing "x =:" in REPL defaultExecutor(rpl, "x =:") - + // Verify variable was set val, exists := vars.GetVariable("x") if !exists { @@ -697,19 +697,19 @@ func TestExecutorWithUnknownCommand(t *testing.T) { func TestDefaultExecutorCodePaths(t *testing.T) { // Test all code paths in defaultExecutor repl := createTestREPL() - + // Path 1: Empty input defaultExecutor(repl, "") - + // Path 2: Built-in command with error (clear should not error but let's verify) defaultExecutor(repl, "clear") - + // Path 3: Built-in command with output (help returns help text) defaultExecutor(repl, "help") - + // Path 4: Unknown command (error handler returns handled=false, err!=nil) defaultExecutor(repl, "completelyunknowncommand123") - + // Path 5: Whitespace only (trimmed to empty, returns early) defaultExecutor(repl, " ") } diff --git a/internal/rpn/metric_test.go b/internal/rpn/metric_test.go index 4ac3238..7441705 100644 --- a/internal/rpn/metric_test.go +++ b/internal/rpn/metric_test.go @@ -98,9 +98,9 @@ func TestMetricRegistryFindCaseInsensitive(t *testing.T) { func TestMetricRegistryDuplicatePanics(t *testing.T) { reg := NewMetricRegistry() reg.Register(&Metric{ - Name: "dup", + Name: "dup", Category: Custom, - Factor: func(PrefixMode) float64 { return 1 }, + Factor: func(PrefixMode) float64 { return 1 }, }) defer func() { if r := recover(); r == nil { @@ -108,9 +108,9 @@ func TestMetricRegistryDuplicatePanics(t *testing.T) { } }() reg.Register(&Metric{ - Name: "dup", + Name: "dup", Category: Custom, - Factor: func(PrefixMode) float64 { return 2 }, + Factor: func(PrefixMode) float64 { return 2 }, }) } @@ -161,9 +161,9 @@ func TestBuiltInMetricFactors(t *testing.T) { tolerance := 0.0001 tests := []struct { - name string - mode PrefixMode - expect float64 + name string + mode PrefixMode + expect float64 }{ // Universal {"Cool", SI, 1}, @@ -177,13 +177,13 @@ func TestBuiltInMetricFactors(t *testing.T) { // DataSize (base: bits) {"bits", SI, 1}, {"bytes", SI, 8}, - {"KB", SI, 8000}, // 8 * 1000 + {"KB", SI, 8000}, // 8 * 1000 {"MB", SI, 8e6}, {"GB", SI, 8e9}, {"TB", SI, 8e12}, {"PB", SI, 8e15}, // IEC (base: bits) - {"KiB", SI, 8192}, // 8 * 1024 + {"KiB", SI, 8192}, // 8 * 1024 {"MiB", SI, 8 * 1048576}, {"GiB", SI, 8 * 1073741824}, {"TiB", SI, 8 * float64(uint64(1)<<40)}, @@ -466,7 +466,7 @@ func TestMetricRegistryAliases(t *testing.T) { reg := GetMetricRegistry() tests := []struct { - alias string + alias string canonical string }{ {"bit/s", "bps"}, @@ -509,9 +509,9 @@ func TestMetricRegistryAliases(t *testing.T) { func TestFindWithAliasesPriority(t *testing.T) { reg := NewMetricRegistry() reg.Register(&Metric{ - Name: "Foo", + Name: "Foo", Category: Custom, - Factor: func(PrefixMode) float64 { return 1 }, + Factor: func(PrefixMode) float64 { return 1 }, }) reg.RegisterAlias("foo", "Foo") @@ -803,7 +803,7 @@ func TestAtPrefixMetricParsing(t *testing.T) { {"@GB", "GB", true}, {"@Mbps", "Mbps", true}, {"@hr", "hr", true}, - {"@sec", "s", true}, // alias + {"@sec", "s", true}, // alias {"@foot", "ft", true}, // alias {"@nope", "", false}, {"@", "", false}, @@ -915,12 +915,12 @@ func TestMetricOperationsUnit(t *testing.T) { tolerance := 0.001 cases := []struct { - name string - setup func(s *Stack) - op func(*Operations, *Stack) error - wantVal float64 - wantMet string - wantErr bool + name string + setup func(s *Stack) + op func(*Operations, *Stack) error + wantVal float64 + wantMet string + wantErr bool }{ { name: "same-category addition 1000bps+1Kbps", diff --git a/internal/rpn/operations_hyper.go b/internal/rpn/operations_hyper.go index b9be48a..087fc67 100644 --- a/internal/rpn/operations_hyper.go +++ b/internal/rpn/operations_hyper.go @@ -265,5 +265,3 @@ func (o *Operations) HyperLog10(stack *Stack) error { func (o *Operations) HyperLn(stack *Stack) error { return o.hyperLog(stack, "[ln]", math.Log, "ln undefined for non-positive numbers") } - - diff --git a/internal/rpn/operations_hyper_test.go b/internal/rpn/operations_hyper_test.go index 4ea7dc6..352e503 100644 --- a/internal/rpn/operations_hyper_test.go +++ b/internal/rpn/operations_hyper_test.go @@ -14,12 +14,12 @@ func TestHyperMetricAwareOperations(t *testing.T) { reg := GetMetricRegistry() tests := []struct { - name string - expr string - wantNum float64 - wantMet string // empty skips metric check - tol float64 - wantErr bool + name string + expr string + wantNum float64 + wantMet string // empty skips metric check + tol float64 + wantErr bool }{ // Addition { @@ -154,7 +154,7 @@ func TestHyperCoolResultOperations(t *testing.T) { wantNum: 3, tol: 0.001, }, { - name: "log2 with metrics", expr: "100Mbps 1000Mbps [lg]", + name: "log2 with metrics", expr: "100Mbps 1000Mbps [lg]", wantNum: math.Log2(100) + math.Log2(1000), tol: 0.01, }, } diff --git a/internal/rpn/operations_test.go b/internal/rpn/operations_test.go index 2592cc7..155a53d 100644 --- a/internal/rpn/operations_test.go +++ b/internal/rpn/operations_test.go @@ -1264,7 +1264,6 @@ func TestOperatorRegistryHandleStandardOperator(t *testing.T) { } } - func TestAssignLeft(t *testing.T) { v := NewVariables() o := NewOperations(v) @@ -1273,8 +1272,8 @@ func TestAssignLeft(t *testing.T) { // For "5 x =:": // AssignLeft pops name first, then value // Push value first (will be popped second), then name (will be popped first) - s.Push(NewNumber(5, FloatMode)) // value (will be popped second) - s.Push(NewStringNum("x")) // name (will be popped first) + s.Push(NewNumber(5, FloatMode)) // value (will be popped second) + s.Push(NewStringNum("x")) // name (will be popped first) err := o.AssignLeft(s) if err != nil { @@ -1304,8 +1303,8 @@ func TestAssignRight(t *testing.T) { // For "x 5 :=": // AssignRight pops value first, then name // Push name first (will be popped second), then value (will be popped first) - s.Push(NewStringNum("x")) // name (will be popped second) - s.Push(NewNumber(5, FloatMode)) // value (will be popped first) + s.Push(NewStringNum("x")) // name (will be popped second) + s.Push(NewNumber(5, FloatMode)) // value (will be popped first) err := o.AssignRight(s) if err != nil { diff --git a/internal/rpn/rpn_parse.go b/internal/rpn/rpn_parse.go index 99b7c25..3633db9 100644 --- a/internal/rpn/rpn_parse.go +++ b/internal/rpn/rpn_parse.go @@ -293,7 +293,7 @@ func (r *RPN) ParseAndEvaluate(input string) (string, error) { func (r *RPN) evaluate(input string, tokens []string) (string, error) { r.mu.Lock() defer r.mu.Unlock() - + // Use the current stack for evaluation to preserve state // This allows incremental operations in REPL mode if r.currentStack == nil { @@ -444,7 +444,7 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) { // For := (right assignment): name value := - first token is always a variable name // For =: (left assignment): value name =: - token before =: is a variable name shouldPushName := false - + if i+1 < len(tokens) { nextToken := tokens[i+1] if nextToken == ":=" || nextToken == "=:" { @@ -476,7 +476,7 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) { } } } - + // Special case: first token in := expression (e.g., "x 5 :=") // Only push as name if the first token is not a number (it's a variable name) if i == 0 && len(tokens) >= 3 && tokens[len(tokens)-1] == ":=" { @@ -484,13 +484,13 @@ func (r *RPN) evaluate(input string, tokens []string) (string, error) { shouldPushName = true } } - + if shouldPushName { // This token is a variable name, push as StringNum stack.Push(NewStringNum(token)) continue } - + // Special case: if token is a defined variable and appears before an assignment operator // (within the next few tokens), push the variable NAME (StringNum) instead of VALUE // to allow reassignment. @@ -585,7 +585,6 @@ func (r *RPN) handleOperator(stack *Stack, token string, tokenIndex int) (string return "", nil } - // Handle standard operators (common logic extracted for DRY) // This must be done BEFORE pushing Symbol for unknown identifiers, // so that operators are properly handled @@ -628,13 +627,13 @@ func isValidIdentifier(token string) bool { if len(token) == 0 { return false } - + // Check first character - must be letter or underscore first := token[0] if !((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_') { return false } - + // Check remaining characters - must be alphanumeric or underscore for i := 1; i < len(token); i++ { c := token[i] @@ -642,7 +641,7 @@ func isValidIdentifier(token string) bool { return false } } - + // Only allow single-character identifiers for symbol support // This prevents words like "what", "is", "of" from becoming symbols return len(token) == 1 diff --git a/internal/rpn/rpn_test.go b/internal/rpn/rpn_test.go index 0822125..0460271 100644 --- a/internal/rpn/rpn_test.go +++ b/internal/rpn/rpn_test.go @@ -682,7 +682,6 @@ func TestRPNIncrementalOperations(t *testing.T) { } } - // TestIncrementalAssignmentRPN tests x =: with value on stack in ParseAndEvaluate func TestIncrementalAssignmentRPN(t *testing.T) { v := NewVariables() @@ -778,24 +777,24 @@ func TestParseAndEvaluateAssignmentLeftRight(t *testing.T) { func TestSymbolPush(t *testing.T) { vars := NewVariables() r := NewRPN(vars) - + // Test :x syntax result, err := r.ParseAndEvaluate(":x") if err != nil { t.Fatalf("ParseAndEvaluate(':x') returned error: %v", err) } - + // The result should be the symbol displayed if result != ":x" { t.Errorf("Expected ':x', got '%s'", result) } - + // Verify the stack has a Symbol stack := r.GetCurrentStack() if len(stack) != 1 { t.Fatalf("Expected 1 item on stack, got %d", len(stack)) } - + // Check that it's a Symbol sym, ok := stack[0].(*Symbol) if !ok { @@ -810,13 +809,13 @@ func TestSymbolPush(t *testing.T) { func TestUnboundIdentifierAsSymbol(t *testing.T) { vars := NewVariables() r := NewRPN(vars) - + // Use bare identifier x (unbound) result, err := r.ParseAndEvaluate("x") if err != nil { t.Fatalf("ParseAndEvaluate('x') returned error: %v", err) } - + // The result should be the symbol displayed if result != ":x" { t.Errorf("Expected ':x', got '%s'", result) @@ -827,18 +826,18 @@ func TestUnboundIdentifierAsSymbol(t *testing.T) { func TestBoundIdentifierPushesValue(t *testing.T) { vars := NewVariables() r := NewRPN(vars) - + // First bind x to 5 if _, err := r.ParseAndEvaluate("x = 5"); err != nil { t.Fatalf("ParseAndEvaluate('x = 5') returned error: %v", err) } - + // Now use x (bound) - should push value result, err := r.ParseAndEvaluate("x") if err != nil { t.Fatalf("ParseAndEvaluate('x') after binding returned error: %v", err) } - + // The result should be 5 if result != "5" { t.Errorf("Expected '5', got '%s'", result) @@ -850,12 +849,12 @@ func TestSymbolWithAssignment(t *testing.T) { // Test :x 10 := (symbol then value with right assignment) vars := NewVariables() r := NewRPN(vars) - + _, err := r.ParseAndEvaluate(":x 10 :=") if err != nil { t.Fatalf("ParseAndEvaluate(':x 10 :=') returned error: %v", err) } - + // Verify x was set to 10 val, exists := vars.GetVariable("x") if !exists { @@ -864,16 +863,16 @@ func TestSymbolWithAssignment(t *testing.T) { if val != 10 { t.Errorf("Variable x = %v, want 10", val) } - + // Test 10 :x =: (value then symbol with left assignment) vars2 := NewVariables() r2 := NewRPN(vars2) - + _, err = r2.ParseAndEvaluate("10 :x =:") if err != nil { t.Fatalf("ParseAndEvaluate('10 :x =:') returned error: %v", err) } - + val, exists = vars2.GetVariable("x") if !exists { t.Errorf("Variable x should exist after assignment") @@ -887,19 +886,19 @@ func TestSymbolWithAssignment(t *testing.T) { func TestStackBasedAssignmentWithSymbol(t *testing.T) { vars := NewVariables() r := NewRPN(vars) - + // Push 42 onto stack _, err := r.ParseAndEvaluate("42") if err != nil { t.Fatalf("ParseAndEvaluate('42') returned error: %v", err) } - + // Now y =: - this should assign 42 to y result, err := r.ParseAndEvaluate("y =:") if err != nil { t.Fatalf("ParseAndEvaluate('y =:') returned error: %v", err) } - + // Verify y was set to 42 val, exists := vars.GetVariable("y") if !exists { @@ -908,7 +907,7 @@ func TestStackBasedAssignmentWithSymbol(t *testing.T) { if val != 42 { t.Errorf("Variable y = %v, want 42", val) } - + // The result should show the assignment confirmation if result != "y = 42" { t.Errorf("Expected 'y = 42', got '%s'", result) -- cgit v1.2.3