Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor command line parameters #17

Merged
merged 2 commits into from
Jul 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 0 additions & 75 deletions base/base.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package base

import "fmt"
import "strings"
import "testing"

type Adaptor interface {
Parse(strictParse bool, input string) Program
}
Expand Down Expand Up @@ -32,74 +28,3 @@ type Expr interface {
AstNode
IsValue() bool
}

/* Test harness functions */

func parseAndCheckOk(a Adaptor, src string) Program {
ast := a.Parse(true, src)
allowStupid := false
ast.Ok(allowStupid)
return ast
}

func ParseAndOkGood(t *testing.T, a Adaptor, src string) Program {
defer func() {
if r := recover(); r != nil {
t.Errorf("Unexpected panic: " + fmt.Sprintf("%v", r) + "\n" +
src)
}
}()
return parseAndCheckOk(a, src)
}

// N.B. do not use to check for bad *syntax* -- see the "[Parser]" panic check
func ParseAndOkBad(t *testing.T, msg string, a Adaptor, src string) Program {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic, but none occurred: " + msg + "\n" +
src)
} else {
rec := fmt.Sprintf("%v", r)
if strings.HasPrefix(rec, "[Parser]") {
t.Errorf("Unexpected panic: " + rec + "\n" + src)
}
// TODO FIXME: check panic more specifically
}
}()
return parseAndCheckOk(a, src)
}

// Pre: parseAndOkGood
func EvalAndOkGood(t *testing.T, p Program, steps int) Program {
defer func() {
if r := recover(); r != nil {
t.Errorf("Unexpected panic: " + fmt.Sprintf("%v", r) + "\n" +
p.String())
}
}()
allowStupid := true
for i := 0; i < steps; i++ {
p, _ = p.Eval() // CHECKME: check rule names as part of test?
p.Ok(allowStupid)
}
return p
}

// Pre: parseAndOkGood
func EvalAndOkBad(t *testing.T, p Program, msg string, steps int) Program {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic, but none occurred: " + msg + "\n" +
p.String())
} else {
// [Parser] panic should be already checked by parseAndOkGood
// TODO FIXME: check panic more specifically
}
}()
allowStupid := true
for i := 0; i < steps; i++ {
p, _ = p.Eval()
p.Ok(allowStupid)
}
return p
}
80 changes: 80 additions & 0 deletions base/testutils/testutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package testutils

import (
"fmt"
"strings"
"testing"

"github.com/rhu1/fgg/base"
)

/* Test harness functions */

func parseAndCheckOk(a base.Adaptor, src string) base.Program {
ast := a.Parse(true, src)
allowStupid := false
ast.Ok(allowStupid)
return ast
}

func ParseAndOkGood(t *testing.T, a base.Adaptor, src string) base.Program {
defer func() {
if r := recover(); r != nil {
t.Errorf("Unexpected panic: " + fmt.Sprintf("%v", r) + "\n" +
src)
}
}()
return parseAndCheckOk(a, src)
}

// N.B. do not use to check for bad *syntax* -- see the "[Parser]" panic check
func ParseAndOkBad(t *testing.T, msg string, a base.Adaptor, src string) base.Program {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic, but none occurred: " + msg + "\n" +
src)
} else {
rec := fmt.Sprintf("%v", r)
if strings.HasPrefix(rec, "[Parser]") {
t.Errorf("Unexpected panic: " + rec + "\n" + src)
}
// TODO FIXME: check panic more specifically
}
}()
return parseAndCheckOk(a, src)
}

// Pre: parseAndOkGood
func EvalAndOkGood(t *testing.T, p base.Program, steps int) base.Program {
defer func() {
if r := recover(); r != nil {
t.Errorf("Unexpected panic: " + fmt.Sprintf("%v", r) + "\n" +
p.String())
}
}()
allowStupid := true
for i := 0; i < steps; i++ {
p, _ = p.Eval() // CHECKME: check rule names as part of test?
p.Ok(allowStupid)
}
return p
}

// Pre: parseAndOkGood
func EvalAndOkBad(t *testing.T, p base.Program, msg string, steps int) base.Program {
defer func() {
if r := recover(); r == nil {
t.Errorf("Expected panic, but none occurred: " + msg + "\n" +
p.String())
} else {
// [Parser] panic should be already checked by parseAndOkGood
// TODO FIXME: check panic more specifically
}
}()
allowStupid := true
for i := 0; i < steps; i++ {
p, _ = p.Eval()
p.Ok(allowStupid)
}
return p
}
17 changes: 9 additions & 8 deletions fg/fg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ import (
"testing"

"github.com/rhu1/fgg/base"
"github.com/rhu1/fgg/base/testutils"
"github.com/rhu1/fgg/fg"
)

/* Harness funcs */

func parseAndOkGood(t *testing.T, elems ...string) base.Program {
var adptr fg.FGAdaptor
return base.ParseAndOkGood(t, &adptr, fg.MakeFgProgram(elems...))
return testutils.ParseAndOkGood(t, &adptr, fg.MakeFgProgram(elems...))
}

// N.B. do not use to check for bad *syntax* -- see the "[Parser]" panic check in base.ParseAndOkBad
func parseAndOkBad(t *testing.T, msg string, elems ...string) base.Program {
var adptr fg.FGAdaptor
return base.ParseAndOkBad(t, msg, &adptr, fg.MakeFgProgram(elems...))
return testutils.ParseAndOkBad(t, msg, &adptr, fg.MakeFgProgram(elems...))
}

/* Syntax and typing */
Expand Down Expand Up @@ -364,15 +365,15 @@ func TestEval001(t *testing.T) {
B := "type B struct { f A }"
e := "B{A{}}.f"
prog := parseAndOkGood(t, A, B, e)
base.EvalAndOkGood(t, prog, 1)
testutils.EvalAndOkGood(t, prog, 1)
}

func TestEval002(t *testing.T) {
A := "type A struct {}"
Am1 := "func (x0 A) m1() A { return x0.m1() }"
e := "A{}.m1()"
prog := parseAndOkGood(t, A, Am1, e)
base.EvalAndOkGood(t, prog, 10)
testutils.EvalAndOkGood(t, prog, 10)
}

func TestEval003(t *testing.T) {
Expand All @@ -381,7 +382,7 @@ func TestEval003(t *testing.T) {
B := "type B struct { f A }"
e := "A{}.m1().f"
prog := parseAndOkGood(t, A, Am1, B, e)
base.EvalAndOkGood(t, prog, 2)
testutils.EvalAndOkGood(t, prog, 2)
}

// Initial testing for assert -- Cf. Test016
Expand All @@ -391,7 +392,7 @@ func TestEval004(t *testing.T) {
A := "type A struct {}"
e := "ToAny{A{}}.any.(A)"
prog := parseAndOkGood(t, Any, ToAny, A, e)
base.EvalAndOkGood(t, prog, 2)
testutils.EvalAndOkGood(t, prog, 2)
}

// Testing isValue on StructLit
Expand All @@ -401,13 +402,13 @@ func TestEval005(t *testing.T) {
A := "type A struct {}"
e := "ToAny{ToAny{ToAny{A{}}.any.(A)}}"
prog := parseAndOkGood(t, Any, ToAny, A, e)
base.EvalAndOkGood(t, prog, 2)
testutils.EvalAndOkGood(t, prog, 2)
}

// //TODO: test -eval=-1 -- test is currently added as -eval=0
func TestEval006(t *testing.T) {
A := "type A struct {}"
e := "A{}"
prog := parseAndOkGood(t, A, e)
base.EvalAndOkGood(t, prog, 0)
testutils.EvalAndOkGood(t, prog, 0)
}
7 changes: 4 additions & 3 deletions fgg/fgg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import (
"testing"

"github.com/rhu1/fgg/base"
"github.com/rhu1/fgg/base/testutils"
"github.com/rhu1/fgg/fgg"
)

/* Harness funcs */

func parseAndOkGood(t *testing.T, elems ...string) base.Program {
var adptr fgg.FGGAdaptor
p := base.ParseAndOkGood(t, &adptr,
p := testutils.ParseAndOkGood(t, &adptr,
fgg.MakeFggProgram(elems...)).(fgg.FGGProgram)
fgg.Monomorph(p)
return p
Expand All @@ -24,7 +25,7 @@ func parseAndOkGood(t *testing.T, elems ...string) base.Program {
// N.B. do not use to check for bad *syntax* -- see the "[Parser]" panic check in base.ParseAndOkBad
func parseAndOkBad(t *testing.T, msg string, elems ...string) base.Program {
var adptr fgg.FGGAdaptor
return base.ParseAndOkBad(t, msg, &adptr, fgg.MakeFggProgram(elems...))
return testutils.ParseAndOkBad(t, msg, &adptr, fgg.MakeFggProgram(elems...))
// Don't attempt monom on bad program
}

Expand Down Expand Up @@ -310,5 +311,5 @@ func TestEval001(t *testing.T) {
Bm := "func (x0 B(type )) m(type a Any())(x1 a) a { return ToAny(){A(){}}.any.(a) }"
e := "B(A()){A(){}}.m(B(A()))(B(A()){A(){}}).f"
prog := parseAndOkGood(t, Any, ToAny, A, B, Bm, e)
base.EvalAndOkBad(t, prog, "Cannot cast A() to B(A())", 3)
testutils.EvalAndOkBad(t, prog, "Cannot cast A() to B(A())", 3)
}
Loading