diff --git a/builtins/core/httpclient/get_test.go b/builtins/core/httpclient/get_test.go index 1d5b29feb..5a53ed293 100644 --- a/builtins/core/httpclient/get_test.go +++ b/builtins/core/httpclient/get_test.go @@ -9,7 +9,7 @@ import ( // TestGet tests the get function func TestGet(t *testing.T) { - count.Tests(t, 1, "TestGet") + count.Tests(t, 1) lang.InitEnv() addr := StartHTTPServer(t) @@ -26,7 +26,7 @@ func TestGet(t *testing.T) { // TestGetFile tests the getfile function func TestGetFile(t *testing.T) { - count.Tests(t, 1, "TestGetFile") + count.Tests(t, 1) lang.InitEnv() addr := StartHTTPServer(t) diff --git a/builtins/core/httpclient/post_test.go b/builtins/core/httpclient/post_test.go index 1013e8a25..7edc18c9d 100644 --- a/builtins/core/httpclient/post_test.go +++ b/builtins/core/httpclient/post_test.go @@ -9,7 +9,7 @@ import ( // TestPost tests the post function func TestPost(t *testing.T) { - count.Tests(t, 1, "TestPost") + count.Tests(t, 1) lang.InitEnv() addr := StartHTTPServer(t) diff --git a/builtins/core/httpclient/server_test.go b/builtins/core/httpclient/server_test.go index 5af9f3888..240980602 100644 --- a/builtins/core/httpclient/server_test.go +++ b/builtins/core/httpclient/server_test.go @@ -33,36 +33,6 @@ func (h testHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -/* -func StartHTTPServer(t *testing.T) (addr string) { - c := make(chan string) - go testHTTPServer(t, c) - addr = <-c - return -} - -func testHTTPServer(t *testing.T, c chan string) { - var ( - port int32 - addr string - err error - ) - - for i := 0; i < 10; i++ { - port = atomic.AddInt32(&testPort, 1) - addr = fmt.Sprintf("%s:%d", testHost, port) - go func() { - err = http.ListenAndServe(addr, testHTTPHandler{}) - }() - time.Sleep(100 * time.Millisecond) - if err == nil { - c <- addr - return - } - } -} -*/ - func StartHTTPServer(t *testing.T) string { var ( port int32 diff --git a/builtins/core/mkarray/case_test.go b/builtins/core/mkarray/case_test.go index aef9e49eb..6c1f015ec 100644 --- a/builtins/core/mkarray/case_test.go +++ b/builtins/core/mkarray/case_test.go @@ -7,7 +7,7 @@ import ( ) func TestGetCase(t *testing.T) { - count.Tests(t, 4, "TestGetCase") + count.Tests(t, 4) if getCase("foobar") != caseLower { t.Error("`foobar` not being detected as lower case") @@ -27,7 +27,7 @@ func TestGetCase(t *testing.T) { } func TestSetCase(t *testing.T) { - count.Tests(t, 3, "TestSetCase") + count.Tests(t, 3) input := "foobar" @@ -62,7 +62,7 @@ func TestSetCase(t *testing.T) { // TestOptimisedSetCase checks that nobody tries to "bug fix" the setCase() // function with lowercasing already lowercased elements func TestOptimisedSetCase(t *testing.T) { - count.Tests(t, 2, "TestOptimisedSetCase") + count.Tests(t, 2) input := "fooBar" diff --git a/builtins/core/mkarray/consts_test.go b/builtins/core/mkarray/consts_test.go index f8fbb090d..6c79a9c00 100644 --- a/builtins/core/mkarray/consts_test.go +++ b/builtins/core/mkarray/consts_test.go @@ -11,7 +11,7 @@ func TestConsts(t *testing.T) { for i, m := range mapRanges { for element := range m { - count.Tests(t, len(m), "TestConsts") + count.Tests(t, len(m)) if element != strings.ToLower(element) { t.Errorf("mapRange contains a non-lowercase element") diff --git a/builtins/core/modules/git_test.go b/builtins/core/modules/git_test.go index 47e96c8d8..4bce5d340 100644 --- a/builtins/core/modules/git_test.go +++ b/builtins/core/modules/git_test.go @@ -8,7 +8,7 @@ import ( ) func TestGitInstalled(t *testing.T) { - count.Tests(t, 1, "TestGitInstalled") + count.Tests(t, 1) if which.Which("git") == "" { t.Log("`git` isn't installed or not in $PATH") @@ -23,7 +23,7 @@ func TestGitUriParser(t *testing.T) { "https://github.com/lmorg/murex-module-murex-dev.git", } - count.Tests(t, len(URIs), "TestGitUriParser") + count.Tests(t, len(URIs)) expected := "murex-module-murex-dev" diff --git a/builtins/core/runtime/runtime_test.go b/builtins/core/runtime/runtime_test.go index 3f919cee0..7fa3cc12e 100644 --- a/builtins/core/runtime/runtime_test.go +++ b/builtins/core/runtime/runtime_test.go @@ -19,6 +19,8 @@ func TestRangeByIndex(t *testing.T) { } func marshalHelp(t *testing.T) string { + t.Helper() + b, err := json.Marshal(help(), false) if err != nil { t.Errorf("Cannot marshal help(): %s", err) diff --git a/builtins/core/typemgmt/variables_test.go b/builtins/core/typemgmt/variables_test.go index 5eaa1f167..6db3c4318 100644 --- a/builtins/core/typemgmt/variables_test.go +++ b/builtins/core/typemgmt/variables_test.go @@ -31,7 +31,7 @@ func VariableTests(tests []Test, t *testing.T) { t.Fatalf("Aborting test because unable to set env: %s", err) } - count.Tests(t, len(tests)*2, "VariableTests") + count.Tests(t, len(tests)*2) defaults.Defaults(lang.InitConf, false) lang.InitEnv() @@ -82,7 +82,7 @@ func UnSetTests(unsetter string, tests []string, t *testing.T) { t.Fatalf("Aborting test because unable to set env: %s", err) } - count.Tests(t, len(tests)*2, "UnSetTests") + count.Tests(t, len(tests)*2) defaults.Defaults(lang.InitConf, false) lang.InitEnv() diff --git a/builtins/core_test.go b/builtins/core_test.go index 46219ee89..0e0339504 100644 --- a/builtins/core_test.go +++ b/builtins/core_test.go @@ -16,12 +16,12 @@ var sourceFile map[string]string // TestCoreDocs tests documentation has been written for core builtins func __TestCoreDocs(t *testing.T) { - count.Tests(t, 1, "TestCoreDocs") + count.Tests(t, 1) test.Exists(t, gopath.Source([]string{"builtins"})+"docgen_test.go") path := gopath.Source([]string{"builtins", "docs"}) - count.Tests(t, len(lang.GoFunctions)*2, "TestCoreDocs") + count.Tests(t, len(lang.GoFunctions)*2) for name := range lang.GoFunctions { syn := docs.Synonym[name] if syn == "" { diff --git a/builtins/types/example/marshal_test.go b/builtins/types/example/marshal_test.go index 178373c20..86b8f438d 100644 --- a/builtins/types/example/marshal_test.go +++ b/builtins/types/example/marshal_test.go @@ -8,7 +8,7 @@ import ( ) func TestMarshal(t *testing.T) { - count.Tests(t, 1, "TestMarshal") + count.Tests(t, 1) lang.InitEnv() fork := lang.ShellProcess.Fork(lang.F_NO_STDOUT) diff --git a/builtins/types/example/unmarshal_test.go b/builtins/types/example/unmarshal_test.go index 817e802d0..0647eb8c4 100644 --- a/builtins/types/example/unmarshal_test.go +++ b/builtins/types/example/unmarshal_test.go @@ -8,7 +8,7 @@ import ( ) func TestUnmarshal(t *testing.T) { - count.Tests(t, 1, "TestUnmarshal") + count.Tests(t, 1) lang.InitEnv() fork := lang.ShellProcess.Fork(lang.F_CREATE_STDIN) diff --git a/builtins/types/json/json_test.go b/builtins/types/json/json_test.go index 2f5e01f38..d209ce561 100644 --- a/builtins/types/json/json_test.go +++ b/builtins/types/json/json_test.go @@ -57,7 +57,7 @@ func TestArrayWriter(t *testing.T) { } func TestMarshalArrayString(t *testing.T) { - count.Tests(t, 1, "TestMarshalArrayString") + count.Tests(t, 1) input := []string{"e", "d", "c", "b", "a"} // lets prove the output retains sorting output := `["e","d","c","b","a"]` @@ -80,7 +80,7 @@ func TestMarshalArrayString(t *testing.T) { } func TestMarshalArrayInt(t *testing.T) { - count.Tests(t, 1, "TestMarshalArrayInt") + count.Tests(t, 1) input := []int{5, 4, 3, 2, 1} // lets prove the output retains sorting output := `[5,4,3,2,1]` diff --git a/builtins/types/toml/toml_test.go b/builtins/types/toml/toml_test.go index 4e6c5a9bd..30c28f6bb 100644 --- a/builtins/types/toml/toml_test.go +++ b/builtins/types/toml/toml_test.go @@ -29,7 +29,7 @@ import ( }*/ func TestArrayWriter(t *testing.T) { - count.Tests(t, 1, "TestArrayWriter") + count.Tests(t, 1) stdout := streams.NewStdin() diff --git a/config/app_test.go b/config/app_test.go index a850d479d..f6a095a34 100644 --- a/config/app_test.go +++ b/config/app_test.go @@ -11,7 +11,7 @@ import ( func TestConsts(t *testing.T) { rx := regexp.MustCompile(`[0-9]+\.[0-9]+\.[0-9]+ ( (ALPHA|BETA|RC[0-9]))?`) - count.Tests(t, 2, "TestConsts") + count.Tests(t, 2) if AppName == "" { t.Error("AppName isn't valid") diff --git a/config/config_test.go b/config/config_test.go index eeb640d6d..3447960f7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -9,7 +9,7 @@ import ( // TestConfig tests the config structure func TestConfig(t *testing.T) { - count.Tests(t, 2, "TestConfig") + count.Tests(t, 2) conf := NewConfiguration() diff --git a/config/defaults/defaults_test.go b/config/defaults/defaults_test.go index 704d047e0..2036be098 100644 --- a/config/defaults/defaults_test.go +++ b/config/defaults/defaults_test.go @@ -9,7 +9,7 @@ import ( // TestDefaultProfileNotEmpty tests the defaults exist func TestDefaultProfileNotEmpty(t *testing.T) { - count.Tests(t, 1, "TestDefaultProfileNotEmpty") + count.Tests(t, 1) s := string(DefaultMurexProfile()) if strings.TrimSpace(s) == "" { diff --git a/config/profile/module_test.go b/config/profile/module_test.go index 7194b96b0..923517570 100644 --- a/config/profile/module_test.go +++ b/config/profile/module_test.go @@ -71,7 +71,7 @@ func testCreateModuleStruct() (posix, plan9, windows Module, err error) { } func TestIsDisabled(t *testing.T) { - count.Tests(t, 3, "TestIsDisabled") + count.Tests(t, 3) disabled = []string{ "foo", @@ -97,7 +97,7 @@ func TestPath(t *testing.T) { t.Skipf("Unable to get current working directory: %s", err) } - count.Tests(t, 2, "TestPath") + count.Tests(t, 2) path := m.Path() @@ -126,7 +126,7 @@ func TestValidate(t *testing.T) { t.Skip("Unable to stat path. Skipping this test until murex is run for the first time") } - count.Tests(t, 6, "TestValidate") + count.Tests(t, 6) autocomplete.GlobalExes = map[string]bool{ "sh": true, diff --git a/debug/badmutex_test.go b/debug/badmutex_test.go index 46e53ad9c..743b7b1ad 100644 --- a/debug/badmutex_test.go +++ b/debug/badmutex_test.go @@ -12,7 +12,7 @@ import ( // TestBadMutex proves our test bad mutex (used to help diagnose locking faults) // does not lock func TestBadMutex(t *testing.T) { - count.Tests(t, 1, "TestBadMutex") + count.Tests(t, 1) var ( m BadMutex // if we swap this for sync.Mutex the error should be raised @@ -37,7 +37,7 @@ func TestBadMutex(t *testing.T) { // TestGoodMutex proves our bad mutex test works func TestGoodMutex(t *testing.T) { - count.Tests(t, 1, "TestGoodMutex") + count.Tests(t, 1) var ( m sync.Mutex // if we swap this for sync.Mutex the error should be raised diff --git a/defaults_test.go b/defaults_test.go index 25a61629a..988acc34d 100644 --- a/defaults_test.go +++ b/defaults_test.go @@ -12,7 +12,7 @@ import ( // TestDefaultConfigExists tests the Default() function populates *config.Config func TestDefaultConfigExists(t *testing.T) { - count.Tests(t, 1, "TestDefaultConfigExists") + count.Tests(t, 1) conf := config.NewConfiguration() @@ -26,7 +26,7 @@ func TestDefaultConfigExists(t *testing.T) { // TestDefaultProfileCompiles test the builtin murex_profile compiles func TestDefaultProfileCompiles(t *testing.T) { - count.Tests(t, 1, "TestDefaultProfileCompiles") + count.Tests(t, 1) defaults.Defaults(lang.InitConf, false) lang.InitEnv() diff --git a/gen/gen_test.go b/gen/gen_test.go index ea171efd8..212986b05 100644 --- a/gen/gen_test.go +++ b/gen/gen_test.go @@ -20,7 +20,7 @@ func (l logger) Write(b []byte) (int, error) { // TestDocgenConfigTemplates tests the config YAML and template files are all // valid and the project can render func TestDocgenConfigTemplates(t *testing.T) { - count.Tests(t, 1, "TestDocgenConfigTemplates") + count.Tests(t, 1) if _, err := os.Stat("gen/docgen.yaml"); os.IsNotExist(err) { os.Chdir("..") diff --git a/gen/website/footer.html b/gen/website/footer.html index 59e1b6a49..6bc9c6d5b 100644 --- a/gen/website/footer.html +++ b/gen/website/footer.html @@ -2,8 +2,10 @@
This site is rebuilt weekly, the content is automatically generated from murex's source code. - Last built on $DATE against commit $COMMITHASHSHORT$COMMITHASHLONG. - Downloadable murex binaries are also built weekly. Current version is $MUREXVERSION which has been verified against $MUREXTESTS unit tests. + Last built on $DATE against commit $COMMITHASHSHORT$COMMITHASHLONG. + Downloadable murex binaries are also built weekly. Current version is $MUREXVERSION which has been verified + against $MUREXTESTS tests.
diff --git a/lang/parser.go b/lang/parser.go index 3e09a5374..7a4a4071e 100644 --- a/lang/parser.go +++ b/lang/parser.go @@ -456,7 +456,7 @@ func parser(block []rune) (nodes astNodes, pErr ParserError) { pUpdate(r) case braceCount > 0: pUpdate(r) - case !scanFuncName: + case !scanFuncName && last != ' ' && last != ':': node.ParamTokens = append(node.ParamTokens, make([]parameters.ParamToken, 1)) pCount++ pToken = &node.ParamTokens[pCount][0] diff --git a/lang/parser_np_test.go b/lang/parser_namedp_test.go similarity index 98% rename from lang/parser_np_test.go rename to lang/parser_namedp_test.go index 06b1527d8..ec40c7cad 100644 --- a/lang/parser_np_test.go +++ b/lang/parser_namedp_test.go @@ -6,11 +6,6 @@ import ( "github.com/lmorg/murex/lang/proc/parameters" ) -type parserTestConditions struct { - Block string - Expected astNodes -} - func TestParserNamedPiped1(t *testing.T) { pipeParams := [][]parameters.ParamToken{{{ Key: "", diff --git a/lang/parser_simple_test.go b/lang/parser_simple_test.go new file mode 100644 index 000000000..1252c2be0 --- /dev/null +++ b/lang/parser_simple_test.go @@ -0,0 +1,360 @@ +package lang + +import ( + "testing" + + "github.com/lmorg/murex/lang/proc/parameters" +) + +func TestParserColon(t *testing.T) { + params := [][]parameters.ParamToken{{{ + Key: "--flag", + Type: parameters.TokenTypeValue, + }}} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example --flag`}, + {Expected: nodes, Block: `example --flag`}, + {Expected: nodes, Block: `example:--flag`}, + {Expected: nodes, Block: `example: --flag`}, + {Expected: nodes, Block: `example: --flag`}, + } + + testParser(t, tests) +} + +func TestParserSpace1(t *testing.T) { + params := [][]parameters.ParamToken{ + {{ + Key: "--flag1", + Type: parameters.TokenTypeValue, + }}, + {{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example:--flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example:--flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example:--flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example --flag1 --flag2`}, + {Expected: nodes, Block: `example:--flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + {Expected: nodes, Block: `example: --flag1 --flag2`}, + } + + testParser(t, tests) +} + +func TestParserSpace2(t *testing.T) { + params := [][]parameters.ParamToken{ + {{ + Key: "--flag1", + Type: parameters.TokenTypeValue, + }}, + {{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + } + + testParser(t, tests) +} + +func TestParserSpace3(t *testing.T) { + params := [][]parameters.ParamToken{ + {{ + Key: "--flag1", + Type: parameters.TokenTypeValue, + }}, + {{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + } + + testParser(t, tests) +} + +func TestParserSpace4(t *testing.T) { + params := [][]parameters.ParamToken{ + {{ + Key: "--flag1", + Type: parameters.TokenTypeValue, + }}, + {{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + } + + testParser(t, tests) +} + +func TestParserSpace5(t *testing.T) { + params := [][]parameters.ParamToken{ + {{ + Key: "--flag1", + Type: parameters.TokenTypeValue, + }}, + {{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example --flag1 --flag2`}, + {Expected: nodes, Block: ` example:--flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + {Expected: nodes, Block: ` example: --flag1 --flag2`}, + } + + testParser(t, tests) +} + +func TestParserCmdQuotes1(t *testing.T) { + params := [][]parameters.ParamToken{{{ + Key: "--flag", + Type: parameters.TokenTypeValue, + }}} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `'example' --flag`}, + {Expected: nodes, Block: `'example' --flag`}, + {Expected: nodes, Block: `'example':--flag`}, + {Expected: nodes, Block: `'example': --flag`}, + {Expected: nodes, Block: `'example': --flag`}, + + {Expected: nodes, Block: `"example" --flag`}, + {Expected: nodes, Block: `"example" --flag`}, + {Expected: nodes, Block: `"example":--flag`}, + {Expected: nodes, Block: `"example": --flag`}, + {Expected: nodes, Block: `"example": --flag`}, + } + + testParser(t, tests) +} + +func TestParserCmdQuotes2(t *testing.T) { + params := [][]parameters.ParamToken{{{ + Key: "--flag", + Type: parameters.TokenTypeValue, + }}} + + nodes := astNodes{{ + NewChain: true, + Name: "example ", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `'example ' --flag`}, + {Expected: nodes, Block: `'example ' --flag`}, + + {Expected: nodes, Block: `"example " --flag`}, + {Expected: nodes, Block: `"example " --flag`}, + } + + testParser(t, tests) +} + +func TestParserCmdQuotes3(t *testing.T) { + params := [][]parameters.ParamToken{{{ + Key: "--flag", + Type: parameters.TokenTypeValue, + }}} + + nodes := astNodes{{ + NewChain: true, + Name: "example:", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `'example:' --flag`}, + {Expected: nodes, Block: `'example:' --flag`}, + + {Expected: nodes, Block: `"example:" --flag`}, + {Expected: nodes, Block: `"example:" --flag`}, + } + + testParser(t, tests) +} + +func TestParserCmdQuotes4(t *testing.T) { + params := [][]parameters.ParamToken{{{ + Key: "--flag2", + Type: parameters.TokenTypeValue, + }}} + + nodes := astNodes{{ + NewChain: true, + Name: "example:--flag1", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `'example:'--flag1 --flag2`}, + {Expected: nodes, Block: `"example:"--flag1 --flag2`}, + } + + testParser(t, tests) +} diff --git a/lang/parser_test.go b/lang/parser_test.go index d704938b6..0607c3b3d 100644 --- a/lang/parser_test.go +++ b/lang/parser_test.go @@ -7,8 +7,15 @@ import ( "github.com/lmorg/murex/utils/json" ) +type parserTestConditions struct { + Block string + Expected astNodes +} + func testParser(t *testing.T, tests []parserTestConditions) { - count.Tests(t, len(tests), "testParser") + t.Helper() + count.Tests(t, len(tests)) + for j := range tests { exp := tests[j].Expected diff --git a/lang/parser_var_block_test.go b/lang/parser_var_block_test.go new file mode 100644 index 000000000..305f8a0c1 --- /dev/null +++ b/lang/parser_var_block_test.go @@ -0,0 +1,66 @@ +package lang + +import ( + "testing" + + "github.com/lmorg/murex/lang/proc/parameters" +) + +func TestParserVariableBlockString1(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-", Type: parameters.TokenTypeValue}, + {Key: "block", Type: parameters.TokenTypeBlockString}, + {Key: "-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example -${block}-`}, + {Expected: nodes, Block: `example "-${block}-"`}, + } + + testParser(t, tests) +} + +func TestParserVariableBlockString2(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-${block}-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example '-${block}-'`}, + {Expected: nodes, Block: `example -\${block}-`}, + {Expected: nodes, Block: `example "-\${block}-"`}, + } + + testParser(t, tests) +} + +func TestParserVariableBlockString3(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-\\${block}-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example '-\${block}-'`}, + } + + testParser(t, tests) +} diff --git a/lang/parser_var_str_test.go b/lang/parser_var_str_test.go new file mode 100644 index 000000000..a28e350dc --- /dev/null +++ b/lang/parser_var_str_test.go @@ -0,0 +1,89 @@ +package lang + +import ( + "testing" + + "github.com/lmorg/murex/lang/proc/parameters" +) + +func TestParserVariableString1(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-", Type: parameters.TokenTypeValue}, + {Key: "var", Type: parameters.TokenTypeString}, + {Key: "-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example -$var-`}, + {Expected: nodes, Block: `example "-$var-"`}, + } + + testParser(t, tests) +} + +func TestParserVariableString2(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-$var-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example '-$var-'`}, + {Expected: nodes, Block: `example -\$var-`}, + {Expected: nodes, Block: `example "-\$var-"`}, + } + + testParser(t, tests) +} + +func TestParserVariableString3(t *testing.T) { + params := [][]parameters.ParamToken{{ + {Key: "-\\$var-", Type: parameters.TokenTypeValue}, + }} + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example '-\$var-'`}, + } + + testParser(t, tests) +} + +/*func TestParserVariableString4(t *testing.T) { + params := [][]parameters.ParamToken{ + {{Key: "-", Type: parameters.TokenTypeValue}}, + {{Key: "var", Type: parameters.TokenTypeString}}, + {{Key: "-", Type: parameters.TokenTypeValue}}, + } + + nodes := astNodes{{ + NewChain: true, + Name: "example", + ParamTokens: params, + }} + + var tests = []parserTestConditions{ + {Expected: nodes, Block: `example - $var -`}, + {Expected: nodes, Block: `example - $var -`}, + {Expected: nodes, Block: `example - "$var" -`}, + {Expected: nodes, Block: `example - "$var" -`}, + } + + testParser(t, tests) +}*/ diff --git a/lang/proc/runmode/runmode_test.go b/lang/proc/runmode/runmode_test.go index 7349ba677..d978279b7 100644 --- a/lang/proc/runmode/runmode_test.go +++ b/lang/proc/runmode/runmode_test.go @@ -8,7 +8,7 @@ import ( // TestRunmodeStringer tests stringer has ran func TestRunmodeStringer(t *testing.T) { - count.Tests(t, 5, "TestRunmodeStringer") + count.Tests(t, 5) defer func() { if r := recover(); r != nil { diff --git a/lang/proc/state/state_test.go b/lang/proc/state/state_test.go index ec6350ef2..fdf6921a9 100644 --- a/lang/proc/state/state_test.go +++ b/lang/proc/state/state_test.go @@ -8,7 +8,7 @@ import ( // TestStateStringer tests stringer has ran func TestStateStringer(t *testing.T) { - count.Tests(t, 9, "TestStateStringer") + count.Tests(t, 9) defer func() { if r := recover(); r != nil { diff --git a/lang/test_units_nil_test.go b/lang/test_units_nil_test.go index 07ba333f0..c83b89744 100644 --- a/lang/test_units_nil_test.go +++ b/lang/test_units_nil_test.go @@ -24,7 +24,7 @@ import ( ) func TestRunTestNotATest(t *testing.T) { - count.Tests(t, 1, "TestRunTestNotATest") + count.Tests(t, 1) lang.InitEnv() lang.ShellProcess.Config.Set("test", "auto-report", false) @@ -58,7 +58,7 @@ func TestRunTestNotATest(t *testing.T) { } func TestRunTestNotAFunction(t *testing.T) { - count.Tests(t, 1, "TestRunTestNotAFunction") + count.Tests(t, 1) lang.InitEnv() lang.ShellProcess.Config.Set("test", "auto-report", false) diff --git a/lang/test_units_test.go b/lang/test_units_test.go index 4750ebd1d..540ba2869 100644 --- a/lang/test_units_test.go +++ b/lang/test_units_test.go @@ -35,7 +35,8 @@ type testUTPs struct { } func testRunTest(t *testing.T, plans []testUTPs) { - count.Tests(t, len(plans)*2, "testRunTest") + t.Helper() + count.Tests(t, len(plans)*2) lang.InitEnv() lang.ShellProcess.Config.Set("test", "auto-report", false) diff --git a/lang/types/define/marshal_test.go b/lang/types/define/marshal_test.go index 95e02c6fe..a8e9a9bda 100644 --- a/lang/types/define/marshal_test.go +++ b/lang/types/define/marshal_test.go @@ -11,7 +11,7 @@ import ( ) func TestMarshalArrayJsonString(t *testing.T) { - count.Tests(t, 1, "TestMarshalArrayJsonString") + count.Tests(t, 1) input := []string{"e", "d", "c", "b", "a"} // lets prove the output retains sorting output := `["e","d","c","b","a"]` @@ -34,7 +34,7 @@ func TestMarshalArrayJsonString(t *testing.T) { } func TestMarshalArrayJsonInt(t *testing.T) { - count.Tests(t, 1, "TestMarshalArrayJsonInt") + count.Tests(t, 1) input := []int{5, 4, 3, 2, 1} // lets prove the output retains sorting output := `[5,4,3,2,1]` diff --git a/lang/types/define/unmarshal_test.go b/lang/types/define/unmarshal_test.go index 5ef0affb5..1b03db6cc 100644 --- a/lang/types/define/unmarshal_test.go +++ b/lang/types/define/unmarshal_test.go @@ -12,7 +12,7 @@ import ( ) func TestUnmarshalArrayJsonString(t *testing.T) { - count.Tests(t, 1, "TestUnmarshalArrayJsonString") + count.Tests(t, 1) input := `["e","d","c","b","a"]` // lets prove the output retains sorting output := `[e d c b a]` @@ -41,7 +41,7 @@ func TestUnmarshalArrayJsonString(t *testing.T) { } func TestUnmarshalArrayJsonInt(t *testing.T) { - count.Tests(t, 1, "TestUnmarshalArrayJsonInt") + count.Tests(t, 1) input := `[5,4,3,2,1]` // lets prove the output retains sorting output := `[5 4 3 2 1]` diff --git a/lang/variables_test.go b/lang/variables_test.go index be9b337e0..4371143b6 100644 --- a/lang/variables_test.go +++ b/lang/variables_test.go @@ -38,6 +38,7 @@ func testVariables(t *testing.T, flags int, details string) { copyBool = false ) + count.Tests(t, 4) p := NewTestProcess() orig := p.Variables @@ -62,7 +63,7 @@ func testVariables(t *testing.T, flags int, details string) { } // Create a referenced variable table - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) fork := p.Fork(flags) copy := fork.Variables @@ -87,7 +88,7 @@ func testVariables(t *testing.T, flags int, details string) { } // test values changed - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) if copy.varTable.vars[0].Value != orig.varTable.vars[0].Value { t.Error("Copy and original shouldn't share same value for number.") @@ -106,7 +107,7 @@ func testVariables(t *testing.T, flags int, details string) { } // test copy values - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) if copy.varTable.vars[0].Value.(float64) != copyNum { t.Error("Copy number not same as expected value.") @@ -125,7 +126,7 @@ func testVariables(t *testing.T, flags int, details string) { } // test GetValue on copy - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) if copy.GetValue("number").(float64) != copyNum { t.Error("Copy var table not returning correct number using GetValue.") @@ -144,7 +145,7 @@ func testVariables(t *testing.T, flags int, details string) { } // test GetString on copy - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) if copy.GetString("number") != types.FloatToString(copyNum) { t.Error("Copy var table not returning correct numeric converted value using GetString.") @@ -162,7 +163,7 @@ func testVariables(t *testing.T, flags int, details string) { t.Error("Copy var table not returning correct boolean converted value using GetString.") } - count.Tests(t, 4, "testVariables") + count.Tests(t, 4) err = copy.Set("new", "string", types.String) if err != nil { t.Error("Unable to create new string. " + err.Error()) @@ -190,7 +191,7 @@ func TestReservedVarables(t *testing.T) { "ARGS", } - count.Tests(t, len(reserved), "TestReservedVarables") + count.Tests(t, len(reserved)) for _, name := range reserved { err := p.Variables.Set(name, "foobar", types.String) diff --git a/main.go b/main.go index 17dc2647a..d2d640a2b 100644 --- a/main.go +++ b/main.go @@ -1,173 +1,150 @@ package main import ( - "compress/gzip" - "io/ioutil" "os" _ "github.com/lmorg/murex/builtins" - "github.com/lmorg/murex/builtins/pipes/term" "github.com/lmorg/murex/config/defaults" "github.com/lmorg/murex/config/profile" "github.com/lmorg/murex/debug" "github.com/lmorg/murex/lang" "github.com/lmorg/murex/lang/ref" "github.com/lmorg/murex/shell" - "github.com/lmorg/murex/utils" - "github.com/lmorg/murex/utils/ansi" ) const ( interactive bool = true nonInteractive bool = false + + envRunTests = "MUREX_TEST_MAIN_RUN_TESTS" ) func main() { readFlags() - lang.InitEnv() switch { case fRunTests: - defaults.Defaults(lang.ShellProcess.Config, nonInteractive) - shell.SignalHandler(nonInteractive) + runTests() - // compiled profile - source := defaults.DefaultMurexProfile() - ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) - execSource(defaults.DefaultMurexProfile(), ref) + case fCommand != "": + runCommandLine(fCommand) - // enable tests - if err := lang.ShellProcess.Config.Set("test", "enabled", true); err != nil { - panic(err) - } - if err := lang.ShellProcess.Config.Set("test", "auto-report", false); err != nil { - panic(err) - } - if err := lang.ShellProcess.Config.Set("test", "verbose", true); err != nil { - panic(err) - } + case len(fSource) > 1: + runSource(fSource[0]) - // run unit tests - passed := lang.GlobalUnitTests.Run(lang.ShellProcess, "*") - lang.ShellProcess.Tests.WriteResults(lang.ShellProcess.Config, lang.ShellProcess.Stdout) + default: + startMurex() + } - if !passed { - os.Exit(1) - } + debug.Log("[FIN]") +} - case fCommand != "": - // default config - defaults.Defaults(lang.ShellProcess.Config, nonInteractive) - shell.SignalHandler(nonInteractive) - - // load modules and profile - if fLoadMods { - // compiled profile - source := defaults.DefaultMurexProfile() - ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) - execSource(defaults.DefaultMurexProfile(), ref) - - // local profile - profile.Execute() - } +func runTests() error { + lang.InitEnv() + + defaults.Defaults(lang.ShellProcess.Config, nonInteractive) + shell.SignalHandler(nonInteractive) - // read block from command line parameters - execSource([]rune(fCommand), nil) + // compiled profile + source := defaults.DefaultMurexProfile() + srcRef := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) + execSource(defaults.DefaultMurexProfile(), srcRef) - case len(fSource) > 0: - // default config - defaults.Defaults(lang.ShellProcess.Config, nonInteractive) - shell.SignalHandler(nonInteractive) + // enable tests + if err := lang.ShellProcess.Config.Set("test", "enabled", true); err != nil { + return err + } + if err := lang.ShellProcess.Config.Set("test", "auto-report", false); err != nil { + return err + } + if err := lang.ShellProcess.Config.Set("test", "verbose", true); err != nil { + return err + } - // load modules a profile - if fLoadMods { - // compiled profile - source := defaults.DefaultMurexProfile() - ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) - execSource(defaults.DefaultMurexProfile(), ref) + // exit early if being run under Go test + if os.Getenv(envRunTests) != "" { + return nil + } - // local profile - profile.Execute() - } + // run unit tests + passed := lang.GlobalUnitTests.Run(lang.ShellProcess, "*") + lang.ShellProcess.Tests.WriteResults(lang.ShellProcess.Config, lang.ShellProcess.Stdout) - // read block from disk - execSource(diskSource(fSource[0]), nil) + if !passed { + os.Exit(1) + } - default: - // default config - defaults.Defaults(lang.ShellProcess.Config, interactive) + return nil +} +func runCommandLine(commandLine string) { + lang.InitEnv() + + // default config + defaults.Defaults(lang.ShellProcess.Config, nonInteractive) + shell.SignalHandler(nonInteractive) + + // load modules and profile + if fLoadMods { // compiled profile source := defaults.DefaultMurexProfile() ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) execSource(defaults.DefaultMurexProfile(), ref) - // load modules and profile + // local profile profile.Execute() - - // start interactive shell - shell.Start() } - debug.Log("[FIN]") + // read block from command line parameters + execSource([]rune(commandLine), nil) } -func diskSource(filename string) []rune { - var b []byte - - file, err := os.Open(filename) - if err != nil { - os.Stderr.WriteString(err.Error() + utils.NewLineString) - os.Exit(1) - } +func runSource(filename string) { + lang.InitEnv() - if len(filename) > 3 && filename[len(filename)-3:] == ".gz" { - gz, err := gzip.NewReader(file) - if err != nil { - file.Close() - os.Stderr.WriteString(err.Error() + utils.NewLineString) - os.Exit(1) - } - b, err = ioutil.ReadAll(gz) + // default config + defaults.Defaults(lang.ShellProcess.Config, nonInteractive) + shell.SignalHandler(nonInteractive) - file.Close() - gz.Close() + // load modules a profile + if fLoadMods { + // compiled profile + source := defaults.DefaultMurexProfile() + ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) + execSource(defaults.DefaultMurexProfile(), ref) - if err != nil { - os.Stderr.WriteString(err.Error() + utils.NewLineString) - os.Exit(1) - } + // local profile + profile.Execute() + } - } else { - b, err = ioutil.ReadAll(file) - file.Close() + // read block from disk + disk, err := diskSource(filename) + if err != nil { + _, err := os.Stderr.WriteString(err.Error() + "\n") if err != nil { - os.Stderr.WriteString(err.Error() + utils.NewLineString) - os.Exit(1) + // wouldn't really make any difference at this point because we + // cannot write to stderr anyway :( + panic(err) } + os.Exit(1) } - - return []rune(string(b)) + execSource([]rune(string(disk)), nil) } -func execSource(source []rune, sourceRef *ref.Source) { - fork := lang.ShellProcess.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN) - fork.Stdout = new(term.Out) - fork.Stderr = term.NewErr(ansi.IsAllowed()) - if sourceRef != nil { - fork.FileRef.Source = sourceRef - } - exitNum, err := fork.Execute(source) +func startMurex() { + lang.InitEnv() - if err != nil { - if exitNum == 0 { - exitNum = 1 - } - os.Stderr.WriteString(err.Error() + utils.NewLineString) - os.Exit(exitNum) - } + // default config + defaults.Defaults(lang.ShellProcess.Config, interactive) - if exitNum != 0 { - os.Exit(exitNum) - } + // compiled profile + source := defaults.DefaultMurexProfile() + ref := ref.History.AddSource("(builtin)", "source/builtin", []byte(string(source))) + execSource(defaults.DefaultMurexProfile(), ref) + + // load modules and profile + profile.Execute() + + // start interactive shell + shell.Start() } diff --git a/main_test.go b/main_test.go new file mode 100644 index 000000000..b5e4344eb --- /dev/null +++ b/main_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "os" + "testing" + + "github.com/lmorg/murex/test/count" +) + +func TestMainRunTests(t *testing.T) { + count.Tests(t, 1) + + if err := os.Setenv(envRunTests, "1"); err != nil { + t.Error(err) + return + } + + if err := runTests(); err != nil { + t.Error(err) + } +} + +func TestRunCommandLine(t *testing.T) { + count.Tests(t, 1) + + runCommandLine(`out: "testing" -> null`) +} + +func TestRunSource(t *testing.T) { + count.Tests(t, 1) + + file := "test/source.mx" + runSource(file) +} + +func TestRunSourceGz(t *testing.T) { + count.Tests(t, 1) + + file := "test/source.mx.gz" + runSource(file) +} diff --git a/murex_test.go b/murex_test.go index 1fec8ebc5..6d29b576b 100644 --- a/murex_test.go +++ b/murex_test.go @@ -10,7 +10,7 @@ import ( // TestMurex tests murex runtime environment can be initialised and and simple // command line can execute func TestMurex(t *testing.T) { - count.Tests(t, 1, "TestMurex") + count.Tests(t, 1) lang.InitEnv() diff --git a/shell/hintsummary/hintsummary_test.go b/shell/hintsummary/hintsummary_test.go index 861dc66da..bd5809776 100644 --- a/shell/hintsummary/hintsummary_test.go +++ b/shell/hintsummary/hintsummary_test.go @@ -8,7 +8,7 @@ import ( // TestHintSummary tests the HintSummary structure func TestHintSummary(t *testing.T) { - count.Tests(t, 4, "TestHintSummary") + count.Tests(t, 4) summary := New() diff --git a/shell/history/colon_test.go b/shell/history/colon_test.go index b02402680..a7268c88b 100644 --- a/shell/history/colon_test.go +++ b/shell/history/colon_test.go @@ -35,7 +35,7 @@ func TestNoColon(t *testing.T) { "command param1 param2 param3", } - count.Tests(t, len(tests), "TestNoColon") + count.Tests(t, len(tests)) for i := range tests { actual := noColon(tests[i]) diff --git a/shell/history/history_test.go b/shell/history/history_test.go index f6361dcec..0ad012e60 100644 --- a/shell/history/history_test.go +++ b/shell/history/history_test.go @@ -52,7 +52,7 @@ func (h *TestHistory) Dump() interface{} { } func TestTestHistory(t *testing.T) { - count.Tests(t, 1, "TestTestHistory") + count.Tests(t, 1) h := NewTestHistory() if h.Len() != len(testHistoryItems) { diff --git a/shell/history/vars_test.go b/shell/history/vars_test.go index 9dd17fd6e..2a30d87b8 100644 --- a/shell/history/vars_test.go +++ b/shell/history/vars_test.go @@ -14,10 +14,9 @@ func newReadlineInstance() *readline.Instance { return rl } -func test(function func(string, *readline.Instance) (string, error), - t *testing.T, tests, expected []string, rl *readline.Instance) { - - count.Tests(t, len(tests), "TestTestHistory") +func test(function func(string, *readline.Instance) (string, error), t *testing.T, tests, expected []string, rl *readline.Instance) { + t.Helper() + count.Tests(t, len(tests)) for i := range tests { actual, err := function(tests[i], rl) diff --git a/shell/variables/expand_test.go b/shell/variables/expand_test.go index db63f546b..ad70538f6 100644 --- a/shell/variables/expand_test.go +++ b/shell/variables/expand_test.go @@ -16,7 +16,7 @@ var ( // TestExpand tests the ExpandString function func TestExpand(t *testing.T) { - count.Tests(t, 1, "TestExpand") + count.Tests(t, 3) // 3 tests in 1 string lang.InitEnv() @@ -41,7 +41,7 @@ func TestExpand(t *testing.T) { // TestExpandString tests the ExpandString function func TestExpandString(t *testing.T) { - count.Tests(t, 1, "TestExpandString") + count.Tests(t, 3) // 3 tests in 1 string lang.InitEnv() @@ -66,7 +66,7 @@ func TestExpandString(t *testing.T) { // TestCompare checks the Expand and ExpandString functions returns the same data (albeit in different data types) func TestCompare(t *testing.T) { - count.Tests(t, 1, "TestCompare") + count.Tests(t, 1) // test comparison r := Expand([]rune(testString)) s := ExpandString(testString) diff --git a/source.go b/source.go new file mode 100644 index 000000000..3e0fe6ead --- /dev/null +++ b/source.go @@ -0,0 +1,69 @@ +package main + +import ( + "compress/gzip" + "io/ioutil" + "os" + + "github.com/lmorg/murex/builtins/pipes/term" + "github.com/lmorg/murex/lang" + "github.com/lmorg/murex/lang/ref" + "github.com/lmorg/murex/utils" + "github.com/lmorg/murex/utils/ansi" +) + +func diskSource(filename string) ([]byte, error) { + var b []byte + + file, err := os.Open(filename) + if err != nil { + return nil, err + } + + if len(filename) > 3 && filename[len(filename)-3:] == ".gz" { + gz, err := gzip.NewReader(file) + if err != nil { + file.Close() + return nil, err + } + b, err = ioutil.ReadAll(gz) + + file.Close() + gz.Close() + + if err != nil { + return nil, err + } + + } else { + b, err = ioutil.ReadAll(file) + file.Close() + if err != nil { + return nil, err + } + } + + return b, nil +} + +func execSource(source []rune, sourceRef *ref.Source) { + fork := lang.ShellProcess.Fork(lang.F_PARENT_VARTABLE | lang.F_NO_STDIN) + fork.Stdout = new(term.Out) + fork.Stderr = term.NewErr(ansi.IsAllowed()) + if sourceRef != nil { + fork.FileRef.Source = sourceRef + } + exitNum, err := fork.Execute(source) + + if err != nil { + if exitNum == 0 { + exitNum = 1 + } + os.Stderr.WriteString(err.Error() + utils.NewLineString) + os.Exit(exitNum) + } + + if exitNum != 0 { + os.Exit(exitNum) + } +} diff --git a/source_test.go b/source_test.go new file mode 100644 index 000000000..6df2c35b6 --- /dev/null +++ b/source_test.go @@ -0,0 +1,52 @@ +package main + +import ( + "testing" + + "github.com/lmorg/murex/lang" + "github.com/lmorg/murex/lang/ref" + "github.com/lmorg/murex/test" + "github.com/lmorg/murex/test/count" +) + +func TestDiskSource(t *testing.T) { + count.Tests(t, 1) + + file := "test/source.mx" + test.Exists(t, file) + + disk, err := diskSource(file) + if err != nil { + t.Error(err) + } + + if len(disk) == 0 { + t.Error(err) + } +} + +func TestDiskSourceGz(t *testing.T) { + count.Tests(t, 1) + + file := "test/source.mx.gz" + test.Exists(t, file) + + disk, err := diskSource(file) + if err != nil { + t.Error(err) + } + + if len(disk) == 0 { + t.Error(err) + } +} + +func TestExecSource(t *testing.T) { + count.Tests(t, 1) + + lang.InitEnv() + + source := `out: "testing"` + srcRef := ref.History.AddSource("(builtin)", "source/builtin", []byte(source)) + execSource([]rune(source), srcRef) +} diff --git a/test/boolean.go b/test/boolean.go index 1d0a86237..48a552017 100644 --- a/test/boolean.go +++ b/test/boolean.go @@ -21,7 +21,8 @@ type BooleanTest struct { // RunBooleanTests runs through all the test cases for BooleanTest. // Please note this shouldn't be confused with the murex scripting language's inbuilt testing framework! func RunBooleanTests(tests []BooleanTest, t *testing.T) { - count.Tests(t, len(tests), "RunBooleanTests") + t.Helper() + count.Tests(t, len(tests)) defaults.Defaults(lang.InitConf, false) lang.InitEnv() diff --git a/test/count/count.go b/test/count/count.go index bd4078272..9225e3cf7 100644 --- a/test/count/count.go +++ b/test/count/count.go @@ -23,10 +23,10 @@ const ( ) // Tests a function to count all the unit tests that have been run -func Tests(t *testing.T, count int, funcName string) { +func Tests(t *testing.T, count int) { switch strings.ToLower(os.Getenv(Env)) { case "log": - t.Logf("%s tests ran: %d", funcName, count) + t.Logf("%s tests ran: %d", t.Name(), count) case "http": httpReq(t, count) diff --git a/test/count/count_test.go b/test/count/count_test.go index 373783402..52466afe9 100644 --- a/test/count/count_test.go +++ b/test/count/count_test.go @@ -4,5 +4,5 @@ import "testing" func TestCountTests(t *testing.T) { // ironically just running the function is enough to test it - Tests(t, 1, "TestCountTests") + Tests(t, 1) } diff --git a/test/count/server/server_test.go b/test/count/server/server_test.go index 445e2f31a..3b905a254 100644 --- a/test/count/server/server_test.go +++ b/test/count/server/server_test.go @@ -19,7 +19,7 @@ import ( // murex project hierarchy) // 2. Test the machine readable total API doesn't suffer a regression bug func TestServer(t *testing.T) { - client.Tests(t, 1, "TestServer") + client.Tests(t, 1) port-- @@ -36,7 +36,7 @@ func TestServer(t *testing.T) { t.SkipNow() } - client.Tests(t, 2, "TestServer") + client.Tests(t, 2) testCount(t) //testT(t) //this test doesn't yet work diff --git a/test/exists.go b/test/exists.go index 5a819e394..3b98a7d84 100644 --- a/test/exists.go +++ b/test/exists.go @@ -9,12 +9,14 @@ import ( // Exists tests if a file exists func Exists(t *testing.T, path string) { + t.Helper() + if os.Getenv("MUREX_TEST_SKIP_EXISTS") != "" { t.Skip("Environmental variable `MUREX_TEST_SKIP_EXISTS` set") return } - count.Tests(t, 1, "Exists") + count.Tests(t, 1) if _, err := os.Stat(path); os.IsNotExist(err) { t.Error("Missing file", path) diff --git a/test/methods.go b/test/methods.go index ebde54183..f8b22613a 100644 --- a/test/methods.go +++ b/test/methods.go @@ -15,7 +15,8 @@ import ( // _ "github.com/lmorg/murex/builtins/types/generic" // _ "github.com/lmorg/murex/builtins/types/json" func RunMethodTest(t *testing.T, cmd func(*lang.Process) error, methodName string, input string, dataType string, params []string, output string, expectedError error) { - count.Tests(t, 1, "RunMethodTest") + t.Helper() + count.Tests(t, 1) p := lang.NewTestProcess() p.IsMethod = true diff --git a/test/murex.go b/test/murex.go index 8a57ddd2f..37db55d90 100644 --- a/test/murex.go +++ b/test/murex.go @@ -20,7 +20,8 @@ type MurexTest struct { // RunMurexTests runs through all the test cases for MurexTest func RunMurexTests(tests []MurexTest, t *testing.T) { - count.Tests(t, len(tests), "RunMurexTests") + t.Helper() + count.Tests(t, len(tests)) defaults.Defaults(lang.InitConf, false) lang.InitEnv() diff --git a/test/source.mx b/test/source.mx new file mode 100644 index 000000000..ca5a6c928 --- /dev/null +++ b/test/source.mx @@ -0,0 +1 @@ +out: "testing" -> null diff --git a/test/source.mx.gz b/test/source.mx.gz new file mode 100644 index 000000000..94bc1e194 Binary files /dev/null and b/test/source.mx.gz differ diff --git a/test/types.go b/test/types.go index 907c73aa8..54266bd52 100644 --- a/test/types.go +++ b/test/types.go @@ -12,7 +12,8 @@ import ( // ArrayWriterTest is an easy template for testing stdio.ArrayWriter methods in murex types func ArrayWriterTest(t *testing.T, dataType string, input []string, expected string) { - count.Tests(t, 1, "ArrayWriterTest") + t.Helper() + count.Tests(t, 1) stdout := streams.NewStdin() @@ -50,7 +51,7 @@ func ArrayWriterTest(t *testing.T, dataType string, input []string, expected str // ReadArrayTest is an easy template for testing stdio.ReadArray methods in murex types func ReadArrayTest(t *testing.T, dataType string, input []byte, expected []string) { - count.Tests(t, 1, "ReadArrayTest") + count.Tests(t, 1) stdout := streams.NewStdin() stdout.SetDataType(dataType) @@ -99,7 +100,7 @@ func (m ReadMapExpected) String() string { // ReadMapOrderedTest is an easy template for testing stdio.ReadMap methods in murex types with ordered maps func ReadMapOrderedTest(t *testing.T, dataType string, input []byte, expected []ReadMapExpected, config *config.Config) { - count.Tests(t, 1, "ReadMapOrderedTest") + count.Tests(t, 1) stdout := streams.NewStdin() stdout.SetDataType(dataType) @@ -134,7 +135,7 @@ func ReadMapOrderedTest(t *testing.T, dataType string, input []byte, expected [] // ReadMapUnorderedTest is an easy template for testing stdio.ReadMap methods in murex types with unordered maps func ReadMapUnorderedTest(t *testing.T, dataType string, input []byte, expected []ReadMapExpected, config *config.Config) { - count.Tests(t, 1, "ReadMapUnorderedTest") + count.Tests(t, 1) stdout := streams.NewStdin() stdout.SetDataType(dataType) diff --git a/utils/ansi/ansi_test.go b/utils/ansi/ansi_test.go index 2d9345a84..eabfc8442 100644 --- a/utils/ansi/ansi_test.go +++ b/utils/ansi/ansi_test.go @@ -11,7 +11,7 @@ import ( // TestAnsiColoured tests writing colours via the ansi package func TestAnsiColoured(t *testing.T) { - count.Tests(t, 1, "TestAnsiColoured") + count.Tests(t, 1) lang.ShellProcess.Config = config.NewConfiguration() lang.ShellProcess.Config.Define("shell", "color", config.Properties{ @@ -38,7 +38,7 @@ func TestAnsiColoured(t *testing.T) { // TestAnsiNoColour tests the color override disables the ansi package func TestAnsiNoColour(t *testing.T) { - count.Tests(t, 1, "TestAnsiNoColour") + count.Tests(t, 1) lang.ShellProcess.Config = config.NewConfiguration() lang.ShellProcess.Config.Define("shell", "color", config.Properties{ diff --git a/utils/consts/consts_test.go b/utils/consts/consts_test.go index 5ff01e0fe..f65cb47e5 100644 --- a/utils/consts/consts_test.go +++ b/utils/consts/consts_test.go @@ -8,7 +8,7 @@ import ( // TestConsts tests the projects constants package func TestTempDir(t *testing.T) { - count.Tests(t, 1, "TestTempDir") + count.Tests(t, 1) if TempDir == "" { t.Error("No temp directory specified") diff --git a/utils/counter/counter_test.go b/utils/counter/counter_test.go index 67452625a..7590eb00d 100644 --- a/utils/counter/counter_test.go +++ b/utils/counter/counter_test.go @@ -7,7 +7,7 @@ import ( ) func TestCounter(t *testing.T) { - count.Tests(t, 2, "TestCounter") + count.Tests(t, 2) mc := new(MutexCounter) i := mc.Add() diff --git a/utils/escape/escape_test.go b/utils/escape/escape_test.go index 2f04110cb..c0cdb26b4 100644 --- a/utils/escape/escape_test.go +++ b/utils/escape/escape_test.go @@ -17,7 +17,9 @@ func TestCommandLine(t *testing.T) { " \t\r\n", } - count.Tests(t, len(s), "TestCommandLine") + for i := range s { + count.Tests(t, len(s[i])) // we are testing every character in batches of strings + } CommandLine(s) @@ -57,7 +59,9 @@ func TestTable(t *testing.T) { " \t\r\n", } - count.Tests(t, len(s), "TestCommandLine") + for i := range s { + count.Tests(t, len(s[i])) // we are testing every character in batches of strings + } Table(s) diff --git a/utils/gopath/gopath_test.go b/utils/gopath/gopath_test.go index 6babd915e..db089d2cd 100644 --- a/utils/gopath/gopath_test.go +++ b/utils/gopath/gopath_test.go @@ -10,7 +10,7 @@ import ( // TestGoPath checks for the existence of GOPATH and warns the user if it is not present func TestGoPath(t *testing.T) { - count.Tests(t, 1, "TestGoPath") + count.Tests(t, 1) GOPATH := os.Getenv("GOPATH") if GOPATH == "" { @@ -32,7 +32,7 @@ func TestGoPath(t *testing.T) { // TestSource just does a quick check that Source() does return the root of // murex's source tree func TestSource(t *testing.T) { - count.Tests(t, 1, "TestSource") + count.Tests(t, 1) path := Source([]string{}) t.Log("Source returns:", path) diff --git a/utils/home/home_test.go b/utils/home/home_test.go index 81d6a7bd1..5218ab709 100644 --- a/utils/home/home_test.go +++ b/utils/home/home_test.go @@ -11,7 +11,7 @@ import ( // TestMyHome tests your home directory can be derived func TestMyHome(t *testing.T) { - count.Tests(t, 1, "TestMyHome") + count.Tests(t, 1) if MyDir == "" { t.Error("MyDir not set (murex will still function)") } @@ -19,7 +19,7 @@ func TestMyHome(t *testing.T) { // TestUserHome tests a users home directory can be derived func TestUserHome(t *testing.T) { - count.Tests(t, 1, "TestUserHome") + count.Tests(t, 1) u, err := user.Current() if err != nil { diff --git a/utils/json/json_test.go b/utils/json/json_test.go index 016bdaa3a..8c43005f6 100644 --- a/utils/json/json_test.go +++ b/utils/json/json_test.go @@ -9,7 +9,7 @@ import ( // TestJsonMap tests the the JSON wrapper can marshal interface{} maps which the // core library cannot func TestJsonMap(t *testing.T) { - count.Tests(t, 1, "TestJsonMap") + count.Tests(t, 1) obj := make(map[interface{}]interface{}) obj["a"] = "b" diff --git a/utils/man/man_unix_test.go b/utils/man/man_unix_test.go index 49f299ed7..c3612b231 100644 --- a/utils/man/man_unix_test.go +++ b/utils/man/man_unix_test.go @@ -16,7 +16,7 @@ func TestMan(t *testing.T) { return } - count.Tests(t, 3, "TestMan") + count.Tests(t, 3) files := GetManPages("cat") if len(files) == 0 { diff --git a/utils/path_test.go b/utils/path_test.go index 324f0ce7f..17a51b9dc 100644 --- a/utils/path_test.go +++ b/utils/path_test.go @@ -10,7 +10,7 @@ import ( // TestNormalisePath tests NormalisePath function func TestNormalisePath(t *testing.T) { - count.Tests(t, 12, "TestNormalisePath") + count.Tests(t, 12) path := NormalisePath(consts.PathSlash) if path != consts.PathSlash { diff --git a/utils/posix/posix_test.go b/utils/posix/posix_test.go index c43f7f739..477681b5d 100644 --- a/utils/posix/posix_test.go +++ b/utils/posix/posix_test.go @@ -20,7 +20,7 @@ func TestPosix(t *testing.T) { "plan9": false, } - count.Tests(t, len(platforms), "TestPosix") + count.Tests(t, len(platforms)) for os, val := range platforms { if val { diff --git a/utils/trim_test.go b/utils/trim_test.go index 2b6542b35..0f58da1f9 100644 --- a/utils/trim_test.go +++ b/utils/trim_test.go @@ -8,7 +8,7 @@ import ( // TestCrLfTrim tests the CrLfTrim function func TestCrLfTrim(t *testing.T) { - count.Tests(t, 5, "TestCrLfTrim") + count.Tests(t, 5) b := []byte("test") @@ -44,7 +44,7 @@ func TestCrLfTrim(t *testing.T) { // TestCrLfTrimRune tests the CrLfTrimRune function func TestCrLfTrimRune(t *testing.T) { - count.Tests(t, 5, "TestCrLfTrimRune") + count.Tests(t, 5) r := []rune("test") @@ -80,7 +80,7 @@ func TestCrLfTrimRune(t *testing.T) { // TestCrLfTrimString tests the CrLfTrimString function func TestCrLfTrimString(t *testing.T) { - count.Tests(t, 5, "TestCrLfTrimString") + count.Tests(t, 5) s := CrLfTrimString("test") diff --git a/utils/url_test.go b/utils/url_test.go index 1a9350066..d77032152 100644 --- a/utils/url_test.go +++ b/utils/url_test.go @@ -26,7 +26,7 @@ func TestIsURL(t *testing.T) { "https://domain", } - count.Tests(t, len(good)+len(bad), "TestCrLfTestIsURLTrimString") + count.Tests(t, len(good)+len(bad)) for _, s := range bad { if IsURL(s) { diff --git a/utils/which/which_test.go b/utils/which/which_test.go index 83572b5e1..793950e81 100644 --- a/utils/which/which_test.go +++ b/utils/which/which_test.go @@ -8,7 +8,7 @@ import ( ) func TestPath(t *testing.T) { - count.Tests(t, 1, "TestPath") + count.Tests(t, 1) path := os.Getenv("PATH") if path == "" { @@ -16,7 +16,7 @@ func TestPath(t *testing.T) { } } func TestWhich(t *testing.T) { - count.Tests(t, 1, "TestWhich") + count.Tests(t, 1) if Which("go") == "" { t.Error("Which() couldn't find the `go` executable in your $PATH")