...

Source file src/github.com/bazelbuild/buildtools/edit/buildozer_command_file_test.go

Documentation: github.com/bazelbuild/buildtools/edit

     1  /*
     2  Copyright 2020 Google LLC
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      https://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package edit
    18  
    19  import (
    20  	"reflect"
    21  	"strconv"
    22  	"strings"
    23  	"testing"
    24  )
    25  
    26  func TestEmptyCommandFileContainsNoCommands(t *testing.T) {
    27  	reader := strings.NewReader("")
    28  	commandsByBuildFile := make(map[string][]commandsForTarget)
    29  	appendCommandsFromReader(NewOpts(), reader, commandsByBuildFile, []string{})
    30  	t.Logf("Read commands:\n%s", prettyFormat(commandsByBuildFile))
    31  
    32  	if len(commandsByBuildFile) != 0 {
    33  		t.Error("No commands should be read")
    34  	}
    35  }
    36  
    37  func TestCommandFileWithOneSetAttributeLineContainsOneCommand(t *testing.T) {
    38  	commands := parseCommandFile("set srcs mytarget.go|//test-project:mytarget\n", t)
    39  	if len(commands) != 1 {
    40  		t.Error("Exactly one command should be read")
    41  		return
    42  	}
    43  	if commands[0].target != "//test-project:mytarget" {
    44  		t.Error("Read command should be for the correct target")
    45  	}
    46  	if !reflect.DeepEqual(commands[0].command, command{[]string{"set", "srcs", "mytarget.go"}}) {
    47  		t.Error("Read command should contain the correct command tokens")
    48  	}
    49  }
    50  
    51  func TestCommandFileWithTwoSetAttributesInOneLineContainsTwoCommands(t *testing.T) {
    52  	commands := parseCommandFile("set srcs mytarget.go|set deps //other-project:othertarget|//test-project:mytarget\n", t)
    53  	if len(commands) != 2 {
    54  		t.Error("Exactly two commands should be read")
    55  		return
    56  	}
    57  	if commands[0].target != "//test-project:mytarget" {
    58  		t.Error("First read command should be for the correct target")
    59  	}
    60  	if !reflect.DeepEqual(commands[0].command, command{[]string{"set", "srcs", "mytarget.go"}}) {
    61  		t.Error("First read command should contain the correct command tokens")
    62  	}
    63  	if commands[1].target != "//test-project:mytarget" {
    64  		t.Error("Second read command should be for the correct target")
    65  	}
    66  	if !reflect.DeepEqual(commands[1].command, command{[]string{"set", "deps", "//other-project:othertarget"}}) {
    67  		t.Error("Second read command should contain the correct command tokens")
    68  	}
    69  }
    70  
    71  func TestCommandFileWithTwoSetAttributesInSeparateLinesContainsTwoCommands(t *testing.T) {
    72  	commands := parseCommandFile("set srcs mytarget.go|//test-project:mytarget\nset deps //other-project:othertarget|//test-project:mytarget\n", t)
    73  	if len(commands) != 2 {
    74  		t.Error("Exactly two commands should be read")
    75  		return
    76  	}
    77  	if commands[0].target != "//test-project:mytarget" {
    78  		t.Error("First read command should be for the correct target")
    79  	}
    80  	if !reflect.DeepEqual(commands[0].command, command{[]string{"set", "srcs", "mytarget.go"}}) {
    81  		t.Error("First read command should contain the correct command tokens")
    82  	}
    83  	if commands[1].target != "//test-project:mytarget" {
    84  		t.Error("Second read command should be for the correct target")
    85  	}
    86  	if !reflect.DeepEqual(commands[1].command, command{[]string{"set", "deps", "//other-project:othertarget"}}) {
    87  		t.Error("Second read command should contain the correct command tokens")
    88  	}
    89  }
    90  
    91  func TestCommandFileWithoutTrailingNewlineContainsCommand(t *testing.T) {
    92  	commands := parseCommandFile("set srcs mytarget.go|//test-project:mytarget", t)
    93  	if len(commands) != 1 {
    94  		t.Error("Exactly one command should be read")
    95  		return
    96  	}
    97  	if commands[0].target != "//test-project:mytarget" {
    98  		t.Error("Read command should be for the correct target")
    99  	}
   100  }
   101  
   102  func TestBlankLinesInCommandFileAreIgnored(t *testing.T) {
   103  	commands := parseCommandFile("set srcs mytarget.go|//test-project:mytarget\n\n\n\n\nset srcs othertarget.go|//test-project:othertarget\n", t)
   104  	if len(commands) != 2 {
   105  		t.Error("Exactly two commands should be read")
   106  	}
   107  }
   108  
   109  func TestLongLineInCommandFileParsesAsOneCommand(t *testing.T) {
   110  	srcsLength := 10000
   111  
   112  	expectedCommandTokens := make([]string, srcsLength+2)
   113  	expectedCommandTokens[0] = "set"
   114  	expectedCommandTokens[1] = "srcs"
   115  	srcs := make([]string, srcsLength)
   116  	for i := 0; i < srcsLength; i++ {
   117  		src := "source_" + strconv.Itoa(i) + ".go"
   118  		srcs[i] = src
   119  		expectedCommandTokens[i+2] = src
   120  	}
   121  
   122  	commands := parseCommandFile("set srcs "+strings.Join(srcs, " ")+"|//test-project:mytarget\n", t)
   123  	if len(commands) != 1 {
   124  		t.Error("Exactly one command should be read")
   125  		return
   126  	}
   127  	if !reflect.DeepEqual(commands[0].command, command{expectedCommandTokens}) {
   128  		t.Errorf("First read command should contain the correct command tokens")
   129  	}
   130  }
   131  
   132  func TestEscapedPipesInCommandFileArentSplit(t *testing.T) {
   133  	commands := parseCommandFile("set srcs mytarget.go|//test-project:mytarget(\\|\\|)\n", t)
   134  	if len(commands) != 1 {
   135  		t.Error("Exactly one command should be read")
   136  	}
   137  	if commands[0].target != "//test-project:mytarget(||)" {
   138  		t.Error("Read command target should be for the correct target")
   139  	}
   140  }
   141  
   142  func parseCommandFile(fileContent string, t *testing.T) []parsedCommand {
   143  	reader := strings.NewReader(fileContent)
   144  	commandsByBuildFile := make(map[string][]commandsForTarget)
   145  	appendCommandsFromReader(NewOpts(), reader, commandsByBuildFile, []string{})
   146  	t.Logf("Read commands:\n%s", prettyFormat(commandsByBuildFile))
   147  	return extractCommands(commandsByBuildFile)
   148  }
   149  
   150  type parsedCommand struct {
   151  	command   command
   152  	target    string
   153  	buildFile string
   154  }
   155  
   156  func extractCommands(commandsByBuildFile map[string][]commandsForTarget) []parsedCommand {
   157  	out := make([]parsedCommand, 0)
   158  	for buildFile, targets := range commandsByBuildFile {
   159  		for _, target := range targets {
   160  			for _, command := range target.commands {
   161  				out = append(out, parsedCommand{command, target.target, buildFile})
   162  			}
   163  		}
   164  	}
   165  	return out
   166  }
   167  
   168  func prettyFormat(commandsByBuildFile map[string][]commandsForTarget) string {
   169  	out := ""
   170  	for buildFile, targets := range commandsByBuildFile {
   171  		out += buildFile + "\n"
   172  		for _, target := range targets {
   173  			out += "  target: " + target.target + "\n"
   174  			for _, command := range target.commands {
   175  				out += "    -"
   176  				for _, token := range command.tokens {
   177  					out += " " + token
   178  				}
   179  				out += "\n"
   180  			}
   181  		}
   182  	}
   183  	return out
   184  }
   185  

View as plain text