package resolver import ( "testing" "golox/ast" "golox/errors" "golox/interpreter" "golox/token" ) func TestResolver_VisitBlockStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) blockStmt := &ast.BlockStmt{ Statements: []ast.Stmt{}, } resolver.VisitBlockStmt(blockStmt) if len(resolver.scopes) != 0 { t.Errorf("expected scopes to be empty, got %v", resolver.scopes) } } func TestResolver_VisitVarStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) varStmt := &ast.VarStmt{ Name: token.Token{Lexeme: "a"}, Initializer: nil, } resolver.VisitVarStmt(varStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitVariableExpr(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) varExpr := &ast.VariableExpr{ Name: token.Token{Lexeme: "a"}, } resolver.VisitVariableExpr(varExpr) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitAssignExpr(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) assignExpr := &ast.AssignExpr{ Name: token.Token{Lexeme: "a"}, Value: &ast.LiteralExpr{Value: 42}, } resolver.VisitAssignExpr(assignExpr) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitFunctionStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) funcStmt := &ast.FunctionStmt{ Name: token.Token{Lexeme: "foo"}, Params: []token.Token{}, Body: []ast.Stmt{}, } resolver.VisitFunctionStmt(funcStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitReturnStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) returnStmt := &ast.ReturnStmt{ Keyword: token.Token{Lexeme: "return"}, Value: &ast.LiteralExpr{Value: 42}, } resolver.currFunc = FunctionFuncType resolver.VisitReturnStmt(returnStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitIfStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) ifStmt := &ast.IfStmt{ Condition: &ast.LiteralExpr{Value: true}, ThenBranch: &ast.BlockStmt{ Statements: []ast.Stmt{}, }, ElseBranch: nil, } resolver.VisitIfStmt(ifStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitWhileStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) whileStmt := &ast.WhileStmt{ Condition: &ast.LiteralExpr{Value: true}, Body: &ast.BlockStmt{ Statements: []ast.Stmt{}, }, } resolver.VisitWhileStmt(whileStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_VisitExpressionStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) exprStmt := &ast.ExpressionStmt{ Expression: &ast.LiteralExpr{Value: 42}, } resolver.VisitExpressionStmt(exprStmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_Resolve(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) stmts := []ast.Stmt{ &ast.BlockStmt{ Statements: []ast.Stmt{ &ast.VarStmt{ Name: token.Token{Lexeme: "a"}, Initializer: nil, }, &ast.VarStmt{ Name: token.Token{Lexeme: "a"}, Initializer: nil, }, }, }, } resolver.Resolve(stmts) if len(logger.Errors) != 1 { t.Errorf("expected 1 error, got %v", logger.Errors) } } func TestResolver_ResolveStmt(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) stmt := &ast.VarStmt{ Name: token.Token{Lexeme: "a"}, Initializer: nil, } resolver.resolveStmt(stmt) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_ResolveExpr(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) expr := &ast.LiteralExpr{Value: 42} resolver.resolveExpr(expr) if len(logger.Errors) != 0 { t.Errorf("expected no errors, got %v", logger.Errors) } } func TestResolver_Declare(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) resolver.beginScope() resolver.declare(&token.Token{Lexeme: "a"}) if len(resolver.scopes) != 1 { t.Errorf("expected 1 scope, got %v", resolver.scopes) } } func TestResolver_Define(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) resolver.beginScope() resolver.define(&token.Token{Lexeme: "a"}) if len(resolver.scopes) != 1 { t.Errorf("expected 1 scope, got %v", resolver.scopes) } } func TestResolver_BeginScope(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) resolver.beginScope() if len(resolver.scopes) != 1 { t.Errorf("expected 1 scope, got %v", resolver.scopes) } } func TestResolver_EndScope(t *testing.T) { logger := errors.NewMockErrorLogger() interp := &interpreter.Interpreter{} resolver := New(interp, logger) resolver.beginScope() resolver.endScope() if len(resolver.scopes) != 0 { t.Errorf("expected 0 scopes, got %v", resolver.scopes) } }