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")