func TestResolveFile(t *testing.T) { for _, test := range resolveFileTest { expectedWrapper := fmt.Sprintf(` node 'x' { class { '__X': } } class __X { %s } `, test.expectedManifest, ) expectedAST := ast.NewAST() err := parser.Parse( expectedAST, "expected.ms", strings.NewReader(expectedWrapper), ) if err != nil { t.Log(expectedWrapper) t.Fatal(err) } realAST := ast.NewAST() realErr := parser.Parse( realAST, "real.ms", strings.NewReader(test.inputManifest), ) if realErr != nil { t.Log(test.inputManifest) t.Fatal(realErr) } if resolvedDecls, err := Resolve(realAST); err != nil { t.Log(test.inputManifest) t.Error(err) } else if decls := expectedAST.Classes[0].Block.Declarations; !ast.DeclarationsEquals(decls, resolvedDecls) { t.Logf("%#v", decls) t.Logf("%#v", resolvedDecls) declsClass := &ast.Class{Block: ast.Block{Declarations: decls}} resolvedDeclsClass := &ast.Class{Block: ast.Block{ Declarations: resolvedDecls, }} t.Log(expectedWrapper) t.Fatalf( "Got bad manifest, expected\n>>%s<< but got\n>>%s<<", declsClass.String(), resolvedDeclsClass.String(), ) } } }
func TestResolveClass(t *testing.T) { for _, test := range resolveClassTest { expectedAST := ast.NewAST() err := parser.Parse( expectedAST, "expected.ms", strings.NewReader(test.expectedManifest), ) if err != nil { t.Log(test.inputManifest) t.Fatal(err) } realAST := ast.NewAST() realErr := parser.Parse( realAST, "real.ms", strings.NewReader(test.inputManifest), ) if realErr != nil { t.Fatal(realErr) } gs := newGlobalState() gs.populateClassesByName(realAST.Classes) gs.populateDefinesByName(realAST.Defines) resolver := newClassResolver( gs, &realAST.Classes[0], nil, "real.ms", realAST.Classes[0].LineNum, ) if resolvedClass, err := resolver.resolve(); err != nil { t.Log(test.inputManifest) t.Fatal(err) } else { c := expectedAST.Classes[0] c.Filename = "real.ms" if !c.Equals(&resolvedClass) { t.Logf("%#v", c) t.Logf("%#v", resolvedClass) t.Fatal( "Got bad manifest, expected", c.String(), "got", resolvedClass.String(), ) } if len(resolver.ls.varDefsByName) != 0 && false { t.Fatal( "Not all variables were resolved in", test.inputManifest, resolver.ls.varDefsByName, ) } } } }
func parseDirAsASTRecursively(ast *ast.AST, dirName string) error { files, filesErr := ioutil.ReadDir(dirName) if filesErr != nil { return filesErr } for _, file := range files { if file.Name()[0] == '.' { continue } fullPath := dirName + "/" + file.Name() if file.IsDir() { if err := parseDirAsASTRecursively(ast, fullPath); err != nil { return err } } else if strings.HasSuffix(file.Name(), ".ms") { f, fErr := os.Open(fullPath) if fErr != nil { return fErr } if err := parser.Parse(ast, fullPath, f); err != nil { f.Close() return err } else { f.Close() } } } return nil }
func TestResolveBadVariable(t *testing.T) { for _, test := range badVariableTest { ast := ast.NewAST() err := parser.Parse( ast, "err.ms", strings.NewReader(test.inputManifest), ) if err != nil { t.Log(test.inputManifest) t.Fatal(err) } gs := newGlobalState() resolver := newClassResolver( gs, &ast.Classes[0], nil, "err.ms", ast.Classes[0].LineNum, ) resolved, resolveErr := resolver.resolve() if resolveErr == nil { t.Log(test.inputManifest) t.Log(&resolved) t.Fatal("Got no error for", test.comment) } else { var e, expE *Err if ce, ok := resolveErr.(*CyclicError); ok { e = &ce.Err } else { e = resolveErr.(*Err) } if ce, ok := test.expectedError.(*CyclicError); ok { expE = &ce.Err } else { expE = test.expectedError.(*Err) } if cyclicE, ok := test.expectedError.(*CyclicError); ok { if re, cyclic := resolveErr.(*CyclicError); !cyclic { t.Log(test.inputManifest) t.Errorf( "%s: Got non-cyclic error: %s", test.comment, resolveErr, ) } else if !reflect.DeepEqual(cyclicE.Cycle, re.Cycle) { t.Log(test.inputManifest) t.Logf("Expected %#v", cyclicE) t.Logf("Got %#v", re) t.Errorf("%s: Got bad cycle error: %s", test.comment, e) } } if e.Line != expE.Line || e.Type != expE.Type { t.Log(test.inputManifest) t.Errorf( "%s: Got bad error: %s. Expected %s", test.comment, e, expE, ) } } } }
func parseDecls(manifest string) ([]Declaration, error) { var ast AST if err := parser.Parse(&ast, "t.ms", strings.NewReader(manifest)); err != nil { return nil, err } if decls, err := resolver.Resolve(&ast); err != nil { return nil, err } else { return decls, nil } }
func TestBadExpressionManifests(t *testing.T) { for _, test := range badExpressionManifests { realManifest := fmt.Sprintf("class c { %s }", test.expression) ast := ast.NewAST() if err := parser.Parse(ast, "test.ms", strings.NewReader(realManifest)); err != nil { t.Log(realManifest) t.Error(err) continue } if _, err := Resolve(ast); err == nil || err.Error() != test.expectedError { t.Log(test.expression) t.Error("Got bad error:", err) } } }
func TestBadDefs(t *testing.T) { for _, test := range badDefsTest { realAST := ast.NewAST() realErr := parser.Parse( realAST, "real.ms", strings.NewReader(test.manifest), ) if realErr != nil { t.Log(test.manifest) t.Fatal(realErr) } if _, err := Resolve(realAST); err == nil { t.Log(test.manifest) t.Error("Got no error for bad file") } else if err.Error() != test.expectedErr { t.Log(test.manifest) t.Error("Got bad error:", err) } } }
func TestConvert(t *testing.T) { for _, test := range convertTests { ast := NewAST() astErr := parser.Parse(ast, "test.ms", strings.NewReader(test.manifest)) if astErr != nil { t.Fatal(astErr) } resolved, resolvedErr := resolver.Resolve(ast) if resolvedErr != nil { t.Log(test.manifest) t.Fatal(resolvedErr) } if steps, err := Convert(resolved); err != nil { t.Fatal(err) } else if !reflect.DeepEqual(steps, test.expectedSteps) { t.Logf("%#v", test.expectedSteps) t.Logf("%#v", steps) t.Error("For", test.manifest, "got bad steps:", steps) } } }
func TestConvertInvalidManifests(t *testing.T) { for _, test := range invalidManifests { ast := NewAST() astErr := parser.Parse(ast, "test.ms", strings.NewReader(test.manifest)) if astErr != nil { t.Log(test.manifest) t.Fatal(astErr) } resolved, resolvedErr := resolver.Resolve(ast) if resolvedErr != nil { t.Log(test.manifest) t.Fatal(resolvedErr) } if _, err := Convert(resolved); err == nil { t.Log(test.manifest) t.Error("Got no error") } else if err.Error() != test.err { t.Log(test.manifest) t.Error("Got bad error:", err.Error()) } } }