From 366936ef0036ea04547c3152a98bda5800208517 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 29 Jul 2021 00:11:15 -0700 Subject: [PATCH] tests: add unit tests for header and template funcs Much of this is being tested with the existing file-based tests in testdata/*, but this moves us toward a much more targetted and simpler test structure. --- main.go | 2 +- main_test.go | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++ tmpl_test.go | 48 +++++++++++++ 3 files changed, 238 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 67e1304..f43350c 100644 --- a/main.go +++ b/main.go @@ -334,5 +334,5 @@ func hasLicense(b []byte) bool { } return bytes.Contains(bytes.ToLower(b[:n]), []byte("copyright")) || bytes.Contains(bytes.ToLower(b[:n]), []byte("mozilla public")) || - bytes.Contains(bytes.ToLower(b[:n]), []byte("SPDX-License-Identifier")) + bytes.Contains(bytes.ToLower(b[:n]), []byte("spdx-license-identifier")) } diff --git a/main_test.go b/main_test.go index 0d9e315..c3445bf 100644 --- a/main_test.go +++ b/main_test.go @@ -15,6 +15,7 @@ package main import ( + "html/template" "io/ioutil" "os" "os/exec" @@ -206,3 +207,191 @@ func TestMPL(t *testing.T) { t.Fatalf("%v\n%s", err, out) } } + +func createTempFile(contents string, pattern string) (*os.File, error) { + f, err := ioutil.TempFile("", pattern) + if err != nil { + return nil, err + } + + if err := ioutil.WriteFile(f.Name(), []byte(contents), 0644); err != nil { + return nil, err + } + + return f, nil +} + +func TestAddLicense(t *testing.T) { + tmpl := template.Must(template.New("").Parse("{{.Holder}}{{.Year}}{{.SPDXID}}")) + data := licenseData{Holder: "H", Year: "Y", SPDXID: "S"} + + tests := []struct { + contents string + wantContents string + wantUpdated bool + }{ + {"", "// HYS\n\n", true}, + {"content", "// HYS\n\ncontent", true}, + + // various headers that should be left intact. Many don't make + // sense for our temp file extension, but that doesn't matter. + {"#!/bin/bash\ncontent", "#!/bin/bash\n// HYS\n\ncontent", true}, + {"\ncontent", "\n// HYS\n\ncontent", true}, + {"\ncontent", "\n// HYS\n\ncontent", true}, + {"\ncontent", "\n// HYS\n\ncontent", true}, + {"# encoding: UTF-8\ncontent", "# encoding: UTF-8\n// HYS\n\ncontent", true}, + {"# frozen_string_literal: true\ncontent", "# frozen_string_literal: true\n// HYS\n\ncontent", true}, + {"\n\n", + }, + { + []string{"f.ml", "f.mli", "f.mll", "f.mly"}, + "(**\n HYS\n*)\n\n", + }, + } + + for _, tt := range tests { + for _, path := range tt.paths { + header, _ := licenseHeader(path, tpl, data) + if got := string(header); got != tt.want { + t.Errorf("licenseHeader(%q) returned: %q, want: %q", path, got, tt.want) + } + } + } +} + +// Test that generated files are properly recognized. +func TestIsGenerated(t *testing.T) { + tests := []struct { + content string + want bool + }{ + {"", false}, + {"Generated", false}, + {"// Code generated by go generate; DO NOT EDIT.", true}, + {"/*\n* Code generated by go generate; DO NOT EDIT.\n*/\n", true}, + {"DO NOT EDIT! Replaced on runs of cargo-raze", true}, + } + + for _, tt := range tests { + b := []byte(tt.content) + if got := isGenerated(b); got != tt.want { + t.Errorf("isGenerated(%q) returned %v, want %v", tt.content, got, tt.want) + } + } +} + +// Test that existing license headers are identified. +func TestHasLicense(t *testing.T) { + tests := []struct { + content string + want bool + }{ + {"", false}, + {"This is my license", false}, + {"This code is released into the public domain.", false}, + {"SPDX: MIT", false}, + + {"Copyright 2000", true}, + {"CoPyRiGhT 2000", true}, + {"Subject to the terms of the Mozilla Public License", true}, + {"SPDX-License-Identifier: MIT", true}, + {"spdx-license-identifier: MIT", true}, + } + + for _, tt := range tests { + b := []byte(tt.content) + if got := hasLicense(b); got != tt.want { + t.Errorf("hasLicense(%q) returned %v, want %v", tt.content, got, tt.want) + } + } +} diff --git a/tmpl_test.go b/tmpl_test.go index 0d9830a..0cff385 100644 --- a/tmpl_test.go +++ b/tmpl_test.go @@ -138,3 +138,51 @@ func TestFetchTemplate(t *testing.T) { }) } } + +func TestExecuteTemplate(t *testing.T) { + tests := []struct { + template string + data licenseData + top, mid, bot string + want string + }{ + { + "", + licenseData{}, + "", "", "", + "\n", + }, + { + "{{.Holder}}{{.Year}}{{.SPDXID}}", + licenseData{Holder: "H", Year: "Y", SPDXID: "S"}, + "", "", "", + "HYS\n\n", + }, + { + "{{.Holder}}{{.Year}}{{.SPDXID}}", + licenseData{Holder: "H", Year: "Y", SPDXID: "S"}, + "", "// ", "", + "// HYS\n\n", + }, + { + "{{.Holder}}{{.Year}}{{.SPDXID}}", + licenseData{Holder: "H", Year: "Y", SPDXID: "S"}, + "/*", " * ", "*/", + "/*\n * HYS\n*/\n\n", + }, + } + + for _, tt := range tests { + tpl, err := template.New("").Parse(tt.template) + if err != nil { + t.Errorf("error parsing template: %v", err) + } + got, err := executeTemplate(tpl, tt.data, tt.top, tt.mid, tt.bot) + if err != nil { + t.Errorf("executeTemplate(%q, %v, %q, %q, %q) returned error: %v", tt.template, tt.data, tt.top, tt.mid, tt.bot, err) + } + if string(got) != tt.want { + t.Errorf("executeTemplate(%q, %v, %q, %q, %q) returned %q, want: %q", tt.template, tt.data, tt.top, tt.mid, tt.bot, string(got), tt.want) + } + } +}