github.com/xzntrc/go-enry/v2@v2.0.0-20230215091818-766cc1d65498/internal/code-generator/generator/heuristics_test.go (about)

     1  package generator
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"go/format"
     7  	"testing"
     8  	"text/template"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestYAMLParsing(t *testing.T) {
    15  	heuristics, err := parseYaml("test_files/heuristics.yml")
    16  
    17  	require.NoError(t, err)
    18  	assert.NotNil(t, heuristics)
    19  
    20  	// extensions
    21  	require.NotNil(t, heuristics.Disambiguations)
    22  	assert.Equal(t, 4, len(heuristics.Disambiguations))
    23  	assert.Equal(t, 2, len(heuristics.Disambiguations[0].Extensions))
    24  
    25  	rules := heuristics.Disambiguations[0].Rules
    26  	assert.Equal(t, 2, len(rules))
    27  	require.Equal(t, "Objective-C", rules[0].Languages[0])
    28  	assert.Equal(t, 1, len(rules[0].Pattern))
    29  
    30  	rules = heuristics.Disambiguations[1].Rules
    31  	assert.Equal(t, 3, len(rules))
    32  	require.Equal(t, "Forth", rules[0].Languages[0])
    33  	require.Equal(t, 2, len(rules[0].Pattern))
    34  
    35  	rules = heuristics.Disambiguations[2].Rules
    36  	assert.Equal(t, 3, len(rules))
    37  	require.Equal(t, "Unix Assembly", rules[1].Languages[0])
    38  	require.NotNil(t, rules[1].And)
    39  	assert.Equal(t, 2, len(rules[1].And))
    40  	require.NotNil(t, rules[1].And[0].NegativePattern)
    41  	assert.Equal(t, "np", rules[1].And[0].NegativePattern)
    42  
    43  	rules = heuristics.Disambiguations[3].Rules
    44  	assert.Equal(t, 1, len(rules))
    45  	assert.Equal(t, "Linux Kernel Module", rules[0].Languages[0])
    46  	assert.Equal(t, "AMPL", rules[0].Languages[1])
    47  
    48  	// named_patterns
    49  	require.NotNil(t, heuristics.NamedPatterns)
    50  	assert.Equal(t, 2, len(heuristics.NamedPatterns))
    51  	assert.Equal(t, 1, len(heuristics.NamedPatterns["fortran"]))
    52  	assert.Equal(t, 2, len(heuristics.NamedPatterns["cpp"]))
    53  }
    54  
    55  func TestSingleRuleLoading(t *testing.T) {
    56  	namedPatterns := map[string]StringArray{"cpp": []string{"cpp_ptrn1", "cpp_ptrn2"}}
    57  	rules := []*Rule{
    58  		&Rule{Languages: []string{"a"}, Patterns: Patterns{NamedPattern: "cpp"}},
    59  		&Rule{Languages: []string{"b"}, And: []*Rule{}},
    60  	}
    61  
    62  	// named_pattern case
    63  	langPattern := loadRule(namedPatterns, rules[0])
    64  	require.Equal(t, "a", langPattern.Langs[0])
    65  	assert.NotEmpty(t, langPattern.Pattern)
    66  
    67  	// and case
    68  	langPattern = loadRule(namedPatterns, rules[1])
    69  	require.Equal(t, "b", langPattern.Langs[0])
    70  }
    71  
    72  func TestLoadingAllHeuristics(t *testing.T) {
    73  	parsedYaml, err := parseYaml("test_files/heuristics.yml")
    74  	require.NoError(t, err)
    75  
    76  	hs, err := loadHeuristics(parsedYaml)
    77  
    78  	// grep -Eo "extensions:\ (.*)" internal/code-generator/generator/test_files/heuristics.yml
    79  	assert.Equal(t, 5, len(hs))
    80  }
    81  
    82  func TestLoadingHeuristicsForSameExt(t *testing.T) {
    83  	parsedYaml := &Heuristics{
    84  		Disambiguations: []*Disambiguation{
    85  			&Disambiguation{
    86  				Extensions: []string{".a", ".b"},
    87  				Rules:      []*Rule{&Rule{Languages: []string{"A"}}},
    88  			},
    89  			&Disambiguation{
    90  				Extensions: []string{".b"},
    91  				Rules:      []*Rule{&Rule{Languages: []string{"B"}}},
    92  			},
    93  		},
    94  	}
    95  
    96  	_, err := loadHeuristics(parsedYaml)
    97  	require.Error(t, err)
    98  }
    99  
   100  func TestTemplateMatcherVars(t *testing.T) {
   101  	parsed, err := parseYaml("test_files/heuristics.yml")
   102  	require.NoError(t, err)
   103  
   104  	heuristics, err := loadHeuristics(parsed)
   105  	require.NoError(t, err)
   106  
   107  	// render a tmpl
   108  	const contentTmpl = "../assets/content.go.tmpl"
   109  	tmpl, err := template.New("content.go.tmpl").Funcs(template.FuncMap{
   110  		"stringVal": func(val string) string {
   111  			return fmt.Sprintf("`%s`", val)
   112  		},
   113  	}).ParseFiles(contentTmpl)
   114  	require.NoError(t, err)
   115  
   116  	buf := bytes.NewBuffer(nil)
   117  	err = tmpl.Execute(buf, heuristics)
   118  	require.NoError(t, err, fmt.Sprintf("%+v", tmpl))
   119  	require.NotEmpty(t, buf)
   120  
   121  	// TODO(bzz) add more advanced test using go/ast package, to verify the
   122  	// structure of generated code:
   123  	//  - check key literal exists in map for each extension:
   124  
   125  	src, err := format.Source(buf.Bytes())
   126  	require.NoError(t, err, "\n%s\n", string(src))
   127  }