parser_test.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package parser
  2. import (
  3. "code.osinet.fr/fgm/waiig15/ast"
  4. "code.osinet.fr/fgm/waiig15/lexer"
  5. "testing"
  6. )
  7. func checkParserErrors(t *testing.T, p *Parser) {
  8. errors := p.Errors()
  9. if len(errors) == 0 {
  10. return;
  11. }
  12. t.Errorf("parser has %d errors", len(errors))
  13. for _, msg := range errors {
  14. t.Errorf("parser error: %q", msg)
  15. }
  16. t.FailNow()
  17. }
  18. func TestLetStatements(t *testing.T) {
  19. // Try removing the ident, the =, or both, to get human-readable errors.
  20. input := `
  21. let x = 5;
  22. let y = 10;
  23. let foobar = 838383;
  24. `
  25. l := lexer.New(input)
  26. p := New(l)
  27. program := p.ParseProgram()
  28. checkParserErrors(t, p)
  29. if program == nil {
  30. t.Fatalf("ParseProgram() returned nil.")
  31. }
  32. if len(program.Statements) != 3 {
  33. t.Fatalf("program.Statements does not contain 3 statements, got=%d",
  34. len(program.Statements))
  35. }
  36. tests := []struct {
  37. expectedIdentifier string
  38. }{
  39. {"x"},
  40. {"y"},
  41. {"foobar"},
  42. }
  43. for i, tt := range tests {
  44. stmt := program.Statements[i]
  45. if !testLetStatement(t, stmt, tt.expectedIdentifier) {
  46. return
  47. }
  48. }
  49. }
  50. func testLetStatement(t *testing.T, s ast.Statement, name string) bool {
  51. if s.TokenLiteral() != "let" {
  52. t.Errorf("s.TokenLiteral not 'let', got=%q", s.TokenLiteral())
  53. return false
  54. }
  55. // Statement is an interface, we need a concrete type for the value, and we
  56. // just determined this looked like a LetStatement.
  57. letStmt, ok := s.(*ast.LetStatement)
  58. if !ok {
  59. t.Errorf("s not *ast.LetStatement{}, got=%T", s)
  60. }
  61. if letStmt.Name.Value != name {
  62. t.Errorf("letStmt.Name.Value not %s, got=%s",
  63. name, letStmt.Name.Value)
  64. return false
  65. }
  66. if letStmt.Name.TokenLiteral() != name {
  67. t.Errorf("letStmt.Name.TokenLiteral not %s, got=%s",
  68. name, letStmt.Name.TokenLiteral())
  69. return false
  70. }
  71. return true
  72. }