github.com/ChicK00o/awgo@v0.29.4/util/scripts_test.go (about)

     1  // Copyright (c) 2018 Dean Jackson <deanishe@deanishe.net>
     2  // MIT Licence - http://opensource.org/licenses/MIT
     3  
     4  package util
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestExecutableRunner(t *testing.T) {
    17  	data := []struct {
    18  		in    string
    19  		valid bool
    20  	}{
    21  		{"", false},
    22  		{"non-existent", false},
    23  		// Directories
    24  		{"/Applications", false},
    25  		{"/var", false}, // symlink on macOS
    26  		{"/", false},
    27  		{"/bin", false},
    28  		// Existing paths
    29  		{"/usr/bin/python2.7", false}, // Missing since macOS 12.3
    30  		{"/usr/bin/python3", true},    // Only included python since macOS 12.3
    31  		{"/bin/cp", true},
    32  		{"/bin/ls", true},
    33  		{"/bin/mv", true},
    34  	}
    35  
    36  	r := ExecRunner{}
    37  	for _, td := range data {
    38  		td := td // pin variable
    39  		t.Run(fmt.Sprintf("CanRunExecutable(%s)", td.in), func(t *testing.T) {
    40  			assert.Equal(t, td.valid, r.CanRun(td.in), "unexpected validity")
    41  
    42  			// Also test runners
    43  			cmd := runners.Cmd(td.in)
    44  			if td.valid {
    45  				assert.NotNil(t, cmd, "valid command rejected")
    46  			} else {
    47  				assert.Nil(t, cmd, "invalid command accepted")
    48  			}
    49  		})
    50  	}
    51  }
    52  
    53  func TestScriptRunner(t *testing.T) {
    54  	tests := []struct {
    55  		in    string
    56  		valid bool
    57  	}{
    58  		{"testdata/applescript.applescript", true},
    59  		{"testdata/applescript.scpt", true},
    60  		{"testdata/bash.sh", true},
    61  		{"testdata/jxa.js", true},
    62  		{"testdata/python.py", true},
    63  		// ScriptRunner can't run executables
    64  		{"testdata/bashx", false},
    65  		{"testdata/pythonx", false},
    66  		// Not scripts
    67  		{"testdata/non-executable", false},
    68  		{"testdata/non-existent", false},
    69  		{"testdata/plain.txt", false},
    70  		{"testdata/perl.pl", false},
    71  	}
    72  
    73  	r := ScriptRunner{DefaultInterpreters}
    74  	for _, td := range tests {
    75  		td := td // pin variable
    76  		t.Run(fmt.Sprintf("CanRunScript(%s)", td.in), func(t *testing.T) {
    77  			assert.Equal(t, td.valid, r.CanRun(td.in), "unexpected validity")
    78  		})
    79  	}
    80  }
    81  
    82  func TestRun(t *testing.T) {
    83  	scripts := []string{
    84  		"testdata/applescript.applescript",
    85  		"testdata/applescript.scpt",
    86  		"testdata/bash.sh",
    87  		"testdata/bashx",
    88  		"testdata/jxa.js",
    89  		"testdata/python.py",
    90  		"testdata/pythonx",
    91  	}
    92  
    93  	for _, script := range scripts {
    94  		script := script // pin variable
    95  		t.Run(fmt.Sprintf("Run(%s)", script), func(t *testing.T) {
    96  			x := filepath.Base(script)
    97  
    98  			// test Run
    99  			out, err := Run(script, x)
   100  			assert.Nil(t, err, "script  %q failed: %v", script, err)
   101  			assert.Equal(t, strings.TrimSpace(string(out)), x, "bad output")
   102  
   103  			// test runners
   104  			out, err = runners.Run(script, x)
   105  			assert.Nil(t, err, "script  %q failed: %v", script, err)
   106  			assert.Equal(t, strings.TrimSpace(string(out)), x, "bad output")
   107  		})
   108  	}
   109  }
   110  
   111  func TestNoRun(t *testing.T) {
   112  	tests := []struct {
   113  		in      string
   114  		unknown bool
   115  		missing bool
   116  	}{
   117  		{"testdata/non-executable", true, false},
   118  		{"testdata/non-existent", false, true},
   119  		{"testdata/plain.txt", true, false},
   120  		{"testdata/perl.pl", true, false},
   121  		{"testdata", true, false},
   122  	}
   123  
   124  	for _, td := range tests {
   125  		td := td // pin variable
   126  		t.Run(fmt.Sprintf("NoRun(%s)", td.in), func(t *testing.T) {
   127  			_, err := Run(td.in, "blah")
   128  			assert.NotNil(t, err, "ran invalid script %q", td.in)
   129  			if td.unknown {
   130  				assert.Equal(t, ErrUnknownFileType, err, "invalid file recognised")
   131  			}
   132  			if td.missing {
   133  				assert.True(t, os.IsNotExist(err), "non-existent file accepted")
   134  			}
   135  
   136  			_, err = runners.Run(td.in, "blah")
   137  			assert.NotNil(t, err, "ran invalid script %q", td.in)
   138  			if td.unknown {
   139  				assert.Equal(t, ErrUnknownFileType, err, "invalid file recognised")
   140  			}
   141  			if td.missing {
   142  				assert.True(t, os.IsNotExist(err), "non-existent file accepted")
   143  			}
   144  		})
   145  	}
   146  }
   147  
   148  // TestNewScriptRunner verifies that ScriptRunner accepts the correct filetypes.
   149  func TestNewScriptRunner(t *testing.T) {
   150  	data := []struct {
   151  		good, bad int
   152  		m         map[string][]string
   153  	}{
   154  		// Python scripts only
   155  		{1, 6, map[string][]string{
   156  			".py": {"/usr/bin/python"},
   157  		}},
   158  		// AppleScripts
   159  		{3, 4, map[string][]string{
   160  			".scpt":        {"/usr/bin/osascript"},
   161  			".applescript": {"/usr/bin/osascript"},
   162  			".js":          {"/usr/bin/osascript", "-l", "JavaScript"},
   163  		}},
   164  	}
   165  
   166  	scripts := []string{
   167  		"testdata/applescript.applescript",
   168  		"testdata/applescript.scpt",
   169  		"testdata/bash.sh",
   170  		"testdata/bashx",
   171  		"testdata/jxa.js",
   172  		"testdata/python.py",
   173  		"testdata/pythonx",
   174  	}
   175  
   176  	for i, td := range data {
   177  		td := td // pin variable
   178  		t.Run(fmt.Sprintf("ScriptRunner(%d)", i), func(t *testing.T) {
   179  			r := NewScriptRunner(td.m)
   180  			var good, bad int
   181  
   182  			for _, script := range scripts {
   183  				if v := r.CanRun(script); v {
   184  					good++
   185  				} else {
   186  					bad++
   187  				}
   188  			}
   189  			assert.Equal(t, td.good, good, "unexpected good count")
   190  			assert.Equal(t, td.bad, bad, "unexpected bad count")
   191  		})
   192  	}
   193  }
   194  
   195  // TestQuoteJS verifies QuoteJS quoting.
   196  func TestQuoteJS(t *testing.T) {
   197  	data := []struct {
   198  		in  interface{}
   199  		out string
   200  	}{
   201  		{"", `""`},
   202  		{"onions", `"onions"`},
   203  		{"", `""`},
   204  		{[]string{"one", "two", "three"}, `["one","two","three"]`},
   205  	}
   206  
   207  	for _, td := range data {
   208  		assert.Equal(t, td.out, QuoteJS(td.in), "unexpected quoted JS")
   209  	}
   210  }