From da8cb40242defc2da8fd4e214b8e7f15f45d37d4 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Sun, 2 Jun 2019 18:48:48 -0400 Subject: [PATCH] lang: If the test fails earlier than expected, exit early If a test failed in stage 2 (fail2) instead of an expected fail in stage 3 (fail3) then it would continue running, which was an undefined behaviour in our API. IOW we should not run Unify if SetScope failed. This patch adds these additional checks to ensure our tests are more robust. --- lang/interpret_test.go | 18 +++++++++--------- lang/structs.go | 4 ++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lang/interpret_test.go b/lang/interpret_test.go index 98703cb6..a50358d3 100644 --- a/lang/interpret_test.go +++ b/lang/interpret_test.go @@ -745,7 +745,7 @@ func TestAstFunc1(t *testing.T) { reader := bytes.NewReader(output.Main) ast, err := LexParse(reader) - if !fail && err != nil { + if (!fail || !fail1) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: lex/parse failed with: %+v", index, err) return @@ -810,7 +810,7 @@ func TestAstFunc1(t *testing.T) { // propagate the scope down through the AST... err = iast.SetScope(scope) - if !fail && err != nil { + if (!fail || !fail2) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: could not set scope: %+v", index, err) return @@ -843,7 +843,7 @@ func TestAstFunc1(t *testing.T) { Logf: xlogf, } err = unifier.Unify() - if !fail && err != nil { + if (!fail || !fail3) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: could not unify types: %+v", index, err) return @@ -868,7 +868,7 @@ func TestAstFunc1(t *testing.T) { // build the function graph graph, err := iast.Graph() - if !fail && err != nil { + if (!fail || !fail4) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: functions failed with: %+v", index, err) return @@ -1156,7 +1156,7 @@ func TestAstFunc2(t *testing.T) { reader := bytes.NewReader(output.Main) ast, err := LexParse(reader) - if !fail && err != nil { + if (!fail || !fail1) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: lex/parse failed with: %+v", index, err) return @@ -1221,7 +1221,7 @@ func TestAstFunc2(t *testing.T) { // propagate the scope down through the AST... err = iast.SetScope(scope) - if !fail && err != nil { + if (!fail || !fail2) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: could not set scope: %+v", index, err) return @@ -1254,7 +1254,7 @@ func TestAstFunc2(t *testing.T) { Logf: xlogf, } err = unifier.Unify() - if !fail && err != nil { + if (!fail || !fail3) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: could not unify types: %+v", index, err) return @@ -1279,7 +1279,7 @@ func TestAstFunc2(t *testing.T) { // build the function graph graph, err := iast.Graph() - if !fail && err != nil { + if (!fail || !fail4) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: functions failed with: %+v", index, err) return @@ -1366,7 +1366,7 @@ func TestAstFunc2(t *testing.T) { ograph, err := interpret(iast) funcs.RUnlock() - if !fail && err != nil { + if (!fail || !fail5) && err != nil { t.Errorf("test #%d: FAIL", index) t.Errorf("test #%d: interpret failed with: %+v", index, err) return diff --git a/lang/structs.go b/lang/structs.go index e42c9111..6f678e33 100644 --- a/lang/structs.go +++ b/lang/structs.go @@ -3143,6 +3143,10 @@ func (obj *StmtInclude) Unify() ([]interfaces.Invariant, error) { if obj.Name == "" { return nil, fmt.Errorf("missing include name") } + if obj.class == nil { + // possible programming error + return nil, fmt.Errorf("include doesn't contain a class pointer yet") + } // is it even possible for the signatures to match? if len(obj.class.Args) != len(obj.Args) {