gopkg.in/mvdan/sh.v1@v1.3.1/cmd/shfmt/main_test.go (about) 1 // Copyright (c) 2016, Daniel Martà <mvdan@mvdan.cc> 2 // See LICENSE for licensing information 3 4 package main 5 6 import ( 7 "bufio" 8 "bytes" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "regexp" 13 "testing" 14 ) 15 16 type action uint 17 18 const ( 19 None action = iota 20 Modify 21 Error 22 ) 23 24 var walkTests = []struct { 25 want action 26 mode os.FileMode 27 path, body string 28 }{ 29 {Modify, 0666, "shebang-1", "#!/bin/sh\n foo"}, 30 {Modify, 0666, "shebang-2", "#!/bin/bash\n foo"}, 31 {Modify, 0666, "shebang-3", "#!/usr/bin/sh\n foo"}, 32 {Modify, 0666, "shebang-4", "#!/usr/bin/env bash\n foo"}, 33 {Modify, 0666, "shebang-5", "#!/bin/env sh\n foo"}, 34 {Modify, 0666, "shebang-space", "#! /bin/sh\n foo"}, 35 {Modify, 0666, "shebang-tabs", "#!\t/bin/env\tsh\n foo"}, 36 {Modify, 0666, "shebang-args", "#!/bin/bash -e -x\nfoo"}, 37 {Modify, 0666, "ext.sh", " foo"}, 38 {Modify, 0666, "ext.bash", " foo"}, 39 {Modify, 0666, "ext-shebang.sh", "#!/bin/sh\n foo"}, 40 {Modify, 0666, filepath.Join("dir", "ext.sh"), " foo"}, 41 {None, 0666, ".hidden", " foo long enough"}, 42 {None, 0666, ".hidden-shebang", "#!/bin/sh\n foo"}, 43 {None, 0666, "..hidden-shebang", "#!/bin/sh\n foo"}, 44 {None, 0666, "noext-empty", " foo"}, 45 {None, 0666, "noext-noshebang", " foo long enough"}, 46 {None, 0666, "shebang-nonewline", "#!/bin/shfoo"}, 47 {None, 0666, "ext.other", " foo"}, 48 {None, 0666, "ext-shebang.other", "#!/bin/sh\n foo"}, 49 {None, 0666, "shebang-nospace", "#!/bin/envsh\n foo"}, 50 {None, 0666, filepath.Join(".git", "ext.sh"), " foo"}, 51 {None, 0666, filepath.Join(".svn", "ext.sh"), " foo"}, 52 {None, 0666, filepath.Join(".hg", "ext.sh"), " foo"}, 53 {Error, 0666, "parse-error.sh", " foo("}, 54 {Error, 0111, "open-error.sh", " foo"}, 55 } 56 57 var errPathMentioned = regexp.MustCompile(`([^ :]+):`) 58 59 func TestWalk(t *testing.T) { 60 dir, err := ioutil.TempDir("", "shfmt-walk") 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer os.RemoveAll(dir) 65 66 if err := os.Chdir(dir); err != nil { 67 t.Fatal(err) 68 } 69 for _, wt := range walkTests { 70 if dir, _ := filepath.Split(wt.path); dir != "" { 71 dir = dir[:len(dir)-1] 72 os.Mkdir(dir, 0777) 73 } 74 err := ioutil.WriteFile(wt.path, []byte(wt.body), wt.mode) 75 if err != nil { 76 t.Fatal(err) 77 } 78 } 79 var outBuf bytes.Buffer 80 out = &outBuf 81 *list, *write = true, true 82 gotError := false 83 errored := map[string]bool{} 84 onError := func(err error) { 85 gotError = true 86 line := err.Error() 87 if sub := errPathMentioned.FindStringSubmatch(line); sub != nil { 88 errored[sub[1]] = true 89 } 90 } 91 doWalk := func(path string) { 92 gotError = false 93 outBuf.Reset() 94 walk(path, onError) 95 } 96 doWalk(".") 97 modified := map[string]bool{} 98 outScan := bufio.NewScanner(&outBuf) 99 for outScan.Scan() { 100 path := outScan.Text() 101 modified[path] = true 102 } 103 for _, wt := range walkTests { 104 t.Run(wt.path, func(t *testing.T) { 105 mod := modified[wt.path] 106 if mod && wt.want != Modify { 107 t.Fatalf("walk had to not run on %s but did", wt.path) 108 } else if !mod && wt.want == Modify { 109 t.Fatalf("walk had to run on %s but didn't", wt.path) 110 } 111 err := errored[wt.path] 112 if err && wt.want != Error { 113 t.Fatalf("walk had to not err on %s but did", wt.path) 114 } else if !err && wt.want == Error { 115 t.Fatalf("walk had to err on %s but didn't", wt.path) 116 } 117 }) 118 } 119 if doWalk("."); outBuf.Len() > 0 { 120 t.Fatal("shfmt -l -w printed paths on a duplicate run") 121 } 122 *list, *write = false, false 123 if doWalk("."); outBuf.Len() == 0 { 124 t.Fatal("shfmt without -l nor -w did not print anything") 125 } 126 if doWalk(".hidden"); outBuf.Len() == 0 { 127 t.Fatal("`shfmt .hidden` did not print anything") 128 } 129 if doWalk("nonexistent"); !gotError { 130 t.Fatal("`shfmt nonexistent` did not error") 131 } 132 if err := ioutil.WriteFile("nowrite", []byte(" foo"), 0444); err != nil { 133 t.Fatal(err) 134 } 135 *write = true 136 if doWalk("nowrite"); !gotError { 137 t.Fatal("`shfmt nowrite` did not error") 138 } 139 }