github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optgen/lang/compiler_test.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package lang
    12  
    13  import (
    14  	"fmt"
    15  	"io"
    16  	"strings"
    17  	"testing"
    18  
    19  	"github.com/cockroachdb/datadriven"
    20  	"github.com/cockroachdb/errors"
    21  )
    22  
    23  func TestCompiler(t *testing.T) {
    24  	datadriven.RunTest(t, "testdata/compiler", func(t *testing.T, d *datadriven.TestData) string {
    25  		// Only compile command supported.
    26  		if d.Cmd != "compile" {
    27  			t.FailNow()
    28  		}
    29  
    30  		c := NewCompiler("test.opt")
    31  		c.SetFileResolver(func(name string) (io.Reader, error) {
    32  			return strings.NewReader(d.Input), nil
    33  		})
    34  
    35  		var actual string
    36  		compiled := c.Compile()
    37  		if compiled != nil {
    38  			actual = compiled.String()
    39  		} else {
    40  			// Concatenate errors.
    41  			for _, err := range c.Errors() {
    42  				actual = fmt.Sprintf("%s%s\n", actual, err.Error())
    43  			}
    44  		}
    45  
    46  		return actual
    47  	})
    48  }
    49  
    50  // Test input file not found.
    51  func TestCompilerFileNotFound(t *testing.T) {
    52  	c := NewCompiler("test.opt")
    53  	c.SetFileResolver(func(name string) (io.Reader, error) {
    54  		return nil, errors.New("file not found")
    55  	})
    56  
    57  	if compiled := c.Compile(); compiled != nil {
    58  		t.Error("expected nil from Compile")
    59  	}
    60  
    61  	if len(c.Errors()) != 1 || c.Errors()[0].Error() != "file not found" {
    62  		t.Errorf("expected error, found: %v", c.Errors())
    63  	}
    64  }
    65  
    66  // Test no input files.
    67  func TestCompilerNoFiles(t *testing.T) {
    68  	c := NewCompiler()
    69  
    70  	if compiled := c.Compile(); compiled == nil {
    71  		t.Errorf("expected empty result, found nil")
    72  	}
    73  }
    74  
    75  // Test multiple input files.
    76  func TestCompilerMultipleFiles(t *testing.T) {
    77  	c := NewCompiler("test.opt", "test2.opt")
    78  	c.SetFileResolver(func(name string) (io.Reader, error) {
    79  		if name == "test.opt" {
    80  			return strings.NewReader("define Foo {}"), nil
    81  		}
    82  		return strings.NewReader("define Bar {}"), nil
    83  	})
    84  
    85  	if compiled := c.Compile(); compiled == nil || len(compiled.Defines) != 2 {
    86  		t.Errorf("expected compiled result with two defines, found: %v", compiled)
    87  	}
    88  }
    89  
    90  // Test multiple input files with errors.
    91  func TestCompilerMultipleErrorFiles(t *testing.T) {
    92  	c := NewCompiler("path/test.opt", "test2.opt")
    93  	c.SetFileResolver(func(name string) (io.Reader, error) {
    94  		if name == "path/test.opt" {
    95  			return strings.NewReader("define Bar {} define Bar {}"), nil
    96  		}
    97  		return strings.NewReader("[Rule] (Unknown) => (Unknown)"), nil
    98  	})
    99  
   100  	if compiled := c.Compile(); compiled != nil {
   101  		t.Error("expected nil result from Compile")
   102  	}
   103  
   104  	if len(c.Errors()) != 2 {
   105  		t.Errorf("expected two errors, found: %v", c.Errors())
   106  	}
   107  
   108  	if c.Errors()[0].Error() != "test.opt:1:15: duplicate 'Bar' define statement" {
   109  		t.Errorf("expected error, found: %v", c.Errors()[0])
   110  	}
   111  
   112  	if c.Errors()[1].Error() != "test2.opt:1:8: unrecognized match name 'Unknown'" {
   113  		t.Errorf("expected error, found: %v", c.Errors()[1])
   114  	}
   115  }