Beispiel #1
0
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(),
			)
		}
	}
}
Beispiel #2
0
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,
				)
			}
		}
	}
}
Beispiel #3
0
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,
				)
			}
		}
	}
}
Beispiel #4
0
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)
		}
	}
}
Beispiel #5
0
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)
		}
	}
}
Beispiel #6
0
func main() {
	help := false
	run := false
	verbose := false
	flag.BoolVar(&help, "h", false, "Shows this message")
	flag.BoolVar(&run, "run", false, "Actually execute the manifest")
	flag.BoolVar(&verbose, "v", false, "Verbose output")

	dirName := "../testdata"
	flag.Parse()

	if help {
		showHelp()
		return
	}

	if args := flag.CommandLine.Args(); len(args) == 1 {
		dirName = args[0]
	}

	mfst := ast.NewAST()
	if err := parseDirAsASTRecursively(mfst, dirName); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(1)
	}

	resolved, resolvedErr := resolver.Resolve(mfst)
	if resolvedErr != nil {
		fmt.Fprintln(os.Stderr, resolvedErr.Error())
		os.Exit(1)
	}

	reduced, reducedErr := reducer.Reduce(resolved)
	if reducedErr != nil {
		fmt.Fprintln(os.Stderr, reducedErr.Error())
		os.Exit(1)
	}

	steps, stepsErr := stepconverter.Convert(reduced)
	if stepsErr != nil {
		fmt.Fprintln(os.Stderr, stepsErr.Error())
		os.Exit(1)
	}

	planner := planner.New()
	plan, planErr := planner.Plan(steps)
	if planErr != nil {
		fmt.Fprintln(os.Stderr, planErr.Error())
		os.Exit(1)
	}

	if run {
		realExc, realExcErr := executor.New("../script")
		if realExcErr != nil {
			fmt.Fprintln(os.Stderr, realExcErr.Error())
			os.Exit(1)
		}
		if err := executor.ExecutePlan(plan, realExc); err != nil {
			fmt.Fprintln(os.Stderr, err.Error())
			os.Exit(1)
		}
	} else {
		exc := executor.DryRun(verbose)
		if err := executor.ExecutePlan(plan, exc); err != nil {
			panic(err)
		}
	}
}