git.templeos.me/xultist/go-enry/v2@v2.0.0-20230215093429-6ef3e87f47c0/utils_test.go (about)

     1  package enry
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  //TODO(bzz): port all from test/test_file_blob.rb test_vendored()
    15  //https://github.com/github/linguist/blob/86adc140d3e8903980565a2984f5532edf4ae875/test/test_file_blob.rb#L270-L583
    16  var vendorTests = []struct {
    17  	path     string
    18  	expected bool
    19  }{
    20  	{"cache/", true},
    21  	{"something_cache/", false},
    22  	{"random/cache/", true},
    23  	{"cache", false},
    24  	{"dependencies/", true},
    25  	{"Dependencies/", true},
    26  	{"dependency/", false},
    27  	{"dist/", true},
    28  	{"dist", false},
    29  	{"random/dist/", true},
    30  	{"random/dist", false},
    31  	{"deps/", true},
    32  	{"foodeps/", false},
    33  	{"configure", true},
    34  	{"a/configure", true},
    35  	{"config.guess", true},
    36  	{"config.guess/", false},
    37  	{".vscode/", true},
    38  	{"doc/_build/", true},
    39  	{"a/docs/_build/", true},
    40  	{"a/dasdocs/_build-vsdoc.js", true},
    41  	{"a/dasdocs/_build-vsdoc.j", false},
    42  	{"foo/bar", false},
    43  	{".sublime-project", true},
    44  	{"foo/vendor/foo", true},
    45  	{"leaflet.draw-src.js", true},
    46  	{"foo/bar/MochiKit.js", true},
    47  	{"foo/bar/dojo.js", true},
    48  	{"foo/env/whatever", true},
    49  	{"some/python/venv/", false},
    50  	{"foo/.imageset/bar", true},
    51  	{"Vagrantfile", true},
    52  	{"src/bootstrap-custom.js", true},
    53  	// {"/css/bootstrap.rtl.css", true}, // from linguist v7.23
    54  }
    55  
    56  func TestIsVendor(t *testing.T) {
    57  	for _, tt := range vendorTests {
    58  		t.Run(tt.path, func(t *testing.T) {
    59  			if got := IsVendor(tt.path); got != tt.expected {
    60  				t.Errorf("IsVendor(%q) = %v, expected %v", tt.path, got, tt.expected)
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func BenchmarkIsVendor(b *testing.B) {
    67  	for i := 0; i < b.N; i++ {
    68  		for _, t := range vendorTests {
    69  			IsVendor(t.path)
    70  		}
    71  	}
    72  }
    73  
    74  func TestIsDocumentation(t *testing.T) {
    75  	tests := []struct {
    76  		name     string
    77  		path     string
    78  		expected bool
    79  	}{
    80  		{name: "TestIsDocumentation_1", path: "foo", expected: false},
    81  		{name: "TestIsDocumentation_2", path: "README", expected: true},
    82  	}
    83  
    84  	for _, test := range tests {
    85  		is := IsDocumentation(test.path)
    86  		assert.Equal(t, is, test.expected, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
    87  	}
    88  }
    89  
    90  func TestIsImage(t *testing.T) {
    91  	tests := []struct {
    92  		name     string
    93  		path     string
    94  		expected bool
    95  	}{
    96  		{name: "TestIsImage_1", path: "invalid.txt", expected: false},
    97  		{name: "TestIsImage_2", path: "image.png", expected: true},
    98  		{name: "TestIsImage_3", path: "image.jpg", expected: true},
    99  		{name: "TestIsImage_4", path: "image.jpeg", expected: true},
   100  		{name: "TestIsImage_5", path: "image.gif", expected: true},
   101  	}
   102  
   103  	for _, test := range tests {
   104  		is := IsImage(test.path)
   105  		assert.Equal(t, is, test.expected, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   106  	}
   107  }
   108  
   109  func TestGetMimeType(t *testing.T) {
   110  	tests := []struct {
   111  		name     string
   112  		path     string
   113  		lang     string
   114  		expected string
   115  	}{
   116  		{name: "TestGetMimeType_1", path: "text.txt", lang: "", expected: "text/plain"},
   117  		{name: "TestGetMimeType_2", path: "file.go", lang: "Go", expected: "text/x-go"},
   118  		{name: "TestGetMimeType_3", path: "image.png", lang: "", expected: "image/png"},
   119  	}
   120  
   121  	for _, test := range tests {
   122  		is := GetMIMEType(test.path, test.lang)
   123  		assert.Equal(t, is, test.expected, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   124  	}
   125  }
   126  
   127  func TestIsConfiguration(t *testing.T) {
   128  	tests := []struct {
   129  		name     string
   130  		path     string
   131  		expected bool
   132  	}{
   133  		{name: "TestIsConfiguration_1", path: "foo", expected: false},
   134  		{name: "TestIsConfiguration_2", path: "foo.ini", expected: true},
   135  		{name: "TestIsConfiguration_3", path: "/test/path/foo.json", expected: true},
   136  	}
   137  
   138  	for _, test := range tests {
   139  		is := IsConfiguration(test.path)
   140  		assert.Equal(t, is, test.expected, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   141  	}
   142  }
   143  
   144  func TestIsBinary(t *testing.T) {
   145  	tests := []struct {
   146  		name     string
   147  		data     []byte
   148  		expected bool
   149  	}{
   150  		{name: "TestIsBinary_1", data: []byte("foo"), expected: false},
   151  		{name: "TestIsBinary_2", data: []byte{0}, expected: true},
   152  		{name: "TestIsBinary_3", data: bytes.Repeat([]byte{'o'}, 8000), expected: false},
   153  	}
   154  
   155  	for _, test := range tests {
   156  		is := IsBinary(test.data)
   157  		assert.Equal(t, is, test.expected, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   158  	}
   159  }
   160  
   161  func TestIsDotFile(t *testing.T) {
   162  	tests := []struct {
   163  		name     string
   164  		path     string
   165  		expected bool
   166  	}{
   167  		{name: "TestIsDotFile_1", path: "foo/bar/./", expected: false},
   168  		{name: "TestIsDotFile_2", path: "./", expected: false},
   169  	}
   170  
   171  	for _, test := range tests {
   172  		is := IsDotFile(test.path)
   173  		assert.Equal(t, test.expected, is, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   174  	}
   175  }
   176  func TestIsTestFile(t *testing.T) {
   177  	tests := []struct {
   178  		name     string
   179  		path     string
   180  		expected bool
   181  	}{
   182  		{name: "TestPHP_Is", path: "tests/FooTest.php", expected: true},
   183  		{name: "TestPHP_Not", path: "foo/FooTest.php", expected: false},
   184  		{name: "TestJava_Is_1", path: "test/FooTest.java", expected: true},
   185  		{name: "TestJava_Is_2", path: "test/FooTests.java", expected: true},
   186  		{name: "TestJava_Is_3", path: "test/TestFoo.java", expected: true},
   187  		{name: "TestJava_Is_4", path: "test/qux/TestFoo.java", expected: true},
   188  		{name: "TestJava_Not", path: "foo/FooTest.java", expected: false},
   189  		{name: "TestScala_Is_1", path: "test/FooTest.scala", expected: true},
   190  		{name: "TestScala_Is_2", path: "test/FooTests.scala", expected: true},
   191  		{name: "TestScala_Is_3", path: "test/FooSpec.scala", expected: true},
   192  		{name: "TestScala_Is_4", path: "test/qux/FooSpecs.scala", expected: true},
   193  		{name: "TestScala_Not", path: "foo/FooTest.scala", expected: false},
   194  		{name: "TestPython_Is", path: "test_foo.py", expected: true},
   195  		{name: "TestPython_Not", path: "foo_test.py", expected: false},
   196  		{name: "TestGo_Is", path: "foo_test.go", expected: true},
   197  		{name: "TestGo_Not", path: "test_foo.go", expected: false},
   198  		{name: "TestRuby_Is_1", path: "foo_test.rb", expected: true},
   199  		{name: "TestRuby_Is_1", path: "foo_spec.rb", expected: true},
   200  		{name: "TestRuby_Not", path: "foo_specs.rb", expected: false},
   201  		{name: "TestCSharp_Is_1", path: "FooTest.cs", expected: true},
   202  		{name: "TestCSharp_Is_2", path: "foo/FooTests.cs", expected: true},
   203  		{name: "TestCSharp_Not", path: "foo/TestFoo.cs", expected: false},
   204  		{name: "TestJavaScript_Is_1", path: "foo.test.js", expected: true},
   205  		{name: "TestJavaScript_Is_2", path: "foo.spec.js", expected: true},
   206  		{name: "TestJavaScript_Not", path: "footest.js", expected: false},
   207  		{name: "TestTypeScript_Is_1", path: "foo.test.ts", expected: true},
   208  		{name: "TestTypeScript_Is_2", path: "foo.spec.ts", expected: true},
   209  		{name: "TestTypeScript_Not", path: "footest.ts", expected: false},
   210  	}
   211  
   212  	for _, test := range tests {
   213  		is := IsTest(test.path)
   214  		assert.Equal(t, test.expected, is, fmt.Sprintf("%v: is = %v, expected: %v", test.name, is, test.expected))
   215  	}
   216  }
   217  
   218  func TestGetColor(t *testing.T) {
   219  	tests := []struct {
   220  		name     string
   221  		language string
   222  		expected string
   223  	}{
   224  		{name: "TestGetColor_1", language: "Go", expected: "#00ADD8"},
   225  		{name: "TestGetColor_2", language: "SomeRandom", expected: "#cccccc"},
   226  		{name: "TestGetColor_3", language: "HTML", expected: "#e34c26"},
   227  		{name: "TestGetColor_4", language: "HTML+PHP", expected: "#4f5d95"},
   228  	}
   229  
   230  	for _, test := range tests {
   231  		color := GetColor(test.language)
   232  		assert.Equal(t, test.expected, color, fmt.Sprintf("%v: is = %v, expected: %v", test.name, color, test.expected))
   233  	}
   234  }
   235  
   236  func TestIsGenerated(t *testing.T) {
   237  	testCases := []struct {
   238  		file      string
   239  		load      bool
   240  		generated bool
   241  	}{
   242  		// Xcode project files
   243  		{"Binary/MainMenu.nib", false, true},
   244  		{"Dummy/foo.xcworkspacedata", false, true},
   245  		{"Dummy/foo.xcuserstate", false, true},
   246  
   247  		//Cocoapods
   248  		{"Pods/Pods.xcodeproj", false, true},
   249  		{"Pods/SwiftDependency/foo.swift", false, true},
   250  		{"Pods/ObjCDependency/foo.h", false, true},
   251  		{"Pods/ObjCDependency/foo.m", false, true},
   252  		{"Dummy/Pods/Pods.xcodeproj", false, true},
   253  		{"Dummy/Pods/SwiftDependency/foo.swift", false, true},
   254  		{"Dummy/Pods/ObjCDependency/foo.h", false, true},
   255  		{"Dummy/Pods/ObjCDependency/foo.m", false, true},
   256  
   257  		//Carthage
   258  		{"Carthage/Build/.Dependency.version", false, true},
   259  		{"Carthage/Build/iOS/Dependency.framework", false, true},
   260  		{"Carthage/Build/Mac/Dependency.framework", false, true},
   261  		{"src/Carthage/Build/.Dependency.version", false, true},
   262  		{"src/Carthage/Build/iOS/Dependency.framework", false, true},
   263  		{"src/Carthage/Build/Mac/Dependency.framework", false, true},
   264  
   265  		//Go-specific vendored paths
   266  		{"go/vendor/github.com/foo.go", false, true},
   267  		{"go/vendor/golang.org/src/foo.c", false, true},
   268  		{"go/vendor/gopkg.in/some/nested/path/foo.go", false, true},
   269  
   270  		//.NET designer file
   271  		{"Dummy/foo.designer.cs", false, true},
   272  		{"Dummy/foo.Designer.cs", false, true},
   273  		{"Dummy/foo.designer.vb", false, true},
   274  		{"Dummy/foo.Designer.vb", false, true},
   275  
   276  		//Composer generated composer.lock file
   277  		{"JSON/composer.lock", false, true},
   278  
   279  		//Node modules
   280  		{"Dummy/node_modules/foo.js", false, true},
   281  
   282  		//npm shrinkwrap file
   283  		{"Dummy/npm-shrinkwrap.json", false, true},
   284  		{"Dummy/package-lock.json", false, true},
   285  		{"JavaScript/jquery-1.6.1.min.js", true, true},
   286  
   287  		//Yarn Plug'n'Play file
   288  		{".pnp.js", false, true},
   289  		{".pnp.cjs", false, true},
   290  		{".pnp.mjs", false, true},
   291  
   292  		//Godep saved dependencies
   293  		{"Godeps/Godeps.json", false, true},
   294  		{"Godeps/_workspace/src/github.com/kr/s3/sign.go", false, true},
   295  
   296  		//Generated by Zephir
   297  		{"C/exception.zep.c", false, true},
   298  		{"C/exception.zep.h", false, true},
   299  		{"PHP/exception.zep.php", false, true},
   300  
   301  		//Minified files
   302  		{"JavaScript/jquery-1.6.1.min.js", true, true},
   303  
   304  		//JavaScript with source-maps
   305  		{"JavaScript/namespace.js", true, true},
   306  		{"Generated/inline.js", true, true},
   307  
   308  		//CSS with source-maps
   309  		{"Generated/linked.css", true, true},
   310  		{"Generated/inline.css", true, true},
   311  
   312  		//Source-map
   313  		{"Data/bootstrap.css.map", true, true},
   314  		{"Generated/linked.css.map", true, true},
   315  		{"Data/sourcemap.v3.map", true, true},
   316  		{"Data/sourcemap.v1.map", true, true},
   317  
   318  		//Specflow
   319  		{"Features/BindingCulture.feature.cs", false, true},
   320  
   321  		//JFlex
   322  		{"Java/JFlexLexer.java", true, true},
   323  
   324  		//GrammarKit
   325  		{"Java/GrammarKit.java", true, true},
   326  
   327  		//roxygen2
   328  		{"R/import.Rd", true, true},
   329  
   330  		//PostScript
   331  		{"PostScript/lambda.pfa", true, true},
   332  
   333  		//Perl ppport.h
   334  		{"Generated/ppport.h", true, true},
   335  
   336  		//Graphql Relay
   337  		{"Javascript/__generated__/App_user.graphql.js", false, true},
   338  
   339  		//Game Maker Studio 2
   340  		{"JSON/GMS2_Project.yyp", true, true},
   341  		{"JSON/2ea73365-b6f1-4bd1-a454-d57a67e50684.yy", true, true},
   342  		{"Generated/options_main.inherited.yy", true, true},
   343  
   344  		//Pipenv
   345  		{"Dummy/Pipfile.lock", false, true},
   346  
   347  		//HTML
   348  		{"HTML/attr-swapped.html", true, true},
   349  		{"HTML/extra-attr.html", true, true},
   350  		{"HTML/extra-spaces.html", true, true},
   351  		{"HTML/extra-tags.html", true, true},
   352  		{"HTML/grohtml.html", true, true},
   353  		{"HTML/grohtml.xhtml", true, true},
   354  		{"HTML/makeinfo.html", true, true},
   355  		{"HTML/mandoc.html", true, true},
   356  		{"HTML/node78.html", true, true},
   357  		{"HTML/org-mode.html", true, true},
   358  		{"HTML/quotes-double.html", true, true},
   359  		{"HTML/quotes-none.html", true, true},
   360  		{"HTML/quotes-single.html", true, true},
   361  		{"HTML/uppercase.html", true, true},
   362  		{"HTML/ronn.html", true, true},
   363  		{"HTML/unknown.html", true, false},
   364  		{"HTML/no-content.html", true, false},
   365  		{"HTML/pages.html", true, true},
   366  
   367  		//GIMP
   368  		{"C/image.c", true, true},
   369  		{"C/image.h", true, true},
   370  
   371  		//Haxe
   372  		{"Generated/Haxe/main.js", true, true},
   373  		{"Generated/Haxe/main.py", true, true},
   374  		{"Generated/Haxe/main.lua", true, true},
   375  		{"Generated/Haxe/Main.cpp", true, true},
   376  		{"Generated/Haxe/Main.h", true, true},
   377  		{"Generated/Haxe/Main.java", true, true},
   378  		{"Generated/Haxe/Main.cs", true, true},
   379  		{"Generated/Haxe/Main.php", true, true},
   380  
   381  		//Poetry lock file
   382  		{"Dummy/poetry.lock", false, true},
   383  	}
   384  
   385  	for _, tt := range testCases {
   386  		t.Run(tt.file, func(t *testing.T) {
   387  			var content []byte
   388  			if tt.load {
   389  				var err error
   390  				content, err = ioutil.ReadFile(filepath.Join("_testdata", tt.file))
   391  				require.NoError(t, err)
   392  			}
   393  
   394  			result := IsGenerated(tt.file, content)
   395  			require.Equal(t, tt.generated, result)
   396  		})
   397  	}
   398  }
   399  
   400  func TestFoo(t *testing.T) {
   401  	file := "HTML/uppercase.html"
   402  	content, err := ioutil.ReadFile("_testdata/" + file)
   403  	require.NoError(t, err)
   404  	require.True(t, IsGenerated(file, content))
   405  }