示例#1
0
// NewAgoraClosure loads a full agora context with the module passed in, then
// returns a closure that calls the 'Run' method on the closure and returns the
// result
func NewAgoraClosure(modPath string) func() string {
	ctx := runtime.NewCtx(new(HTTPResolver), new(compiler.Compiler))
	f, _ := os.Open(modPath)
	defer f.Close()

	ctx.Compiler.Compile(modPath, f)

	ctx.RegisterNativeModule(new(stdlib.FmtMod))
	ctx.RegisterNativeModule(new(stdlib.FilepathMod))
	ctx.RegisterNativeModule(new(stdlib.ConvMod))
	ctx.RegisterNativeModule(new(stdlib.StringsMod))
	ctx.RegisterNativeModule(new(stdlib.MathMod))
	ctx.RegisterNativeModule(new(stdlib.OsMod))
	ctx.RegisterNativeModule(new(stdlib.TimeMod))

	mod, err := ctx.Load(modPath)
	if err != nil {
		fmt.Println("Couldn't load module", err.Error())
		os.Exit(1)
	}

	return func() string {

		val, err := mod.Run()
		if err != nil {
			fmt.Println("Error executing module", err.Error())
			os.Exit(1)
		}

		return val.String()
	}
}
示例#2
0
func TestMin(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	mm := new(MathMod)
	mm.SetCtx(ctx)

	cases := []struct {
		src []runtime.Val
		exp runtime.Val
	}{
		0: {
			src: []runtime.Val{runtime.Number(3), runtime.Number(0), runtime.Number(-12.74), runtime.Number(1)},
			exp: runtime.Number(-12.74),
		},
		1: {
			src: []runtime.Val{runtime.String("24"), runtime.Bool(true), runtime.Number(12.74)},
			exp: runtime.Number(1),
		},
		2: {
			src: []runtime.Val{runtime.Number(0), runtime.String("0")},
			exp: runtime.Number(0),
		},
	}

	for i, c := range cases {
		ret := mm.math_Min(c.src...)
		if ret != c.exp {
			t.Errorf("[%d] - expected %f, got %f", i, c.exp.Float(), ret.Float())
		}
	}
}
示例#3
0
func TestStringsSplit(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_Split(runtime.String("aa:bb::dd"), runtime.String(":"))
	ob := ret.(runtime.Object)
	exp := []string{"aa", "bb", "", "dd"}
	if l := ob.Len().Int(); l != int64(len(exp)) {
		t.Errorf("expected split length of %d, got %d", len(exp), l)
	}
	for i, v := range exp {
		got := ob.Get(runtime.Number(i))
		if got.String() != v {
			t.Errorf("expected split index %d to be %s, got %s", i, v, got)
		}
	}
	ret = sm.strings_Split(runtime.String("aa:bb::dd:ee:"), runtime.String(":"), runtime.Number(2))
	ob = ret.(runtime.Object)
	exp = []string{"aa", "bb::dd:ee:"}
	if l := ob.Len().Int(); l != int64(len(exp)) {
		t.Errorf("expected split length of %d, got %d", len(exp), l)
	}
	for i, v := range exp {
		got := ob.Get(runtime.Number(i))
		if got.String() != v {
			t.Errorf("expected split index %d to be %s, got %s", i, v, got)
		}
	}
}
示例#4
0
func TestOsFields(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	ob, err := om.Run()
	if err != nil {
		panic(err)
	}
	{
		ob := ob.(runtime.Object)
		ret := ob.Get(runtime.String("PathSeparator"))
		exp := string(os.PathSeparator)
		if ret.String() != exp {
			t.Errorf("expected path separator %s, got %s", exp, ret.String())
		}
		ret = ob.Get(runtime.String("PathListSeparator"))
		exp = string(os.PathListSeparator)
		if ret.String() != exp {
			t.Errorf("expected path list separator %s, got %s", exp, ret.String())
		}
		ret = ob.Get(runtime.String("DevNull"))
		exp = os.DevNull
		if ret.String() != exp {
			t.Errorf("expected dev/null %s, got %s", exp, ret)
		}
		ret = ob.Get(runtime.String("TempDir"))
		exp = os.TempDir()
		if ret.String() != exp {
			t.Errorf("expected temp dir %s, got %s", exp, ret)
		}
	}
}
示例#5
0
func TestOsOpen(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	fn := "./testdata/readfile.txt"
	f := om.os_Open(runtime.String(fn))
	fl := f.(*file)
	ret := fl.Get(runtime.String("Name"))
	if ret.String() != fn {
		t.Errorf("expected Name to be '%s', got '%s'", fn, ret)
	}
	exp := "ok"
	ret = fl.readLine()
	if ret.String() != exp {
		t.Errorf("expected read line 1 to be '%s', got '%s'", exp, ret)
	}
	exp = ""
	ret = fl.readLine()
	if ret.String() != exp {
		t.Errorf("expected read line 2 to be '%s', got '%s'", exp, ret)
	}
	ret = fl.readLine()
	if ret != runtime.Nil {
		t.Errorf("expected read line 3 to be nil, got '%v'", ret)
	}
	ret = fl.closeFile()
	if ret != runtime.Nil {
		t.Errorf("expected close file to be nil, got '%v'", ret)
	}
}
示例#6
0
func TestTimeConv(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	tm := new(TimeMod)
	tm.SetCtx(ctx)
	nw := time.Now().UTC()
	n := tm.time_Date(runtime.Number(nw.Year()),
		runtime.Number(nw.Month()),
		runtime.Number(nw.Day()),
		runtime.Number(nw.Hour()),
		runtime.Number(nw.Minute()),
		runtime.Number(nw.Second()),
		runtime.Number(nw.Nanosecond()))
	ob := n.(runtime.Object)
	cnv := ob.Get(runtime.String("__string"))
	f := cnv.(runtime.Func)
	ret := f.Call(nil)
	exp := nw.Format(time.RFC3339)
	if ret.String() != exp {
		t.Errorf("expected string to return '%s', got '%s'", exp, ret)
	}
	cnv = ob.Get(runtime.String("__int"))
	f = cnv.(runtime.Func)
	ret = f.Call(nil)
	{
		exp := nw.Unix()
		if ret.Int() != int64(exp) {
			t.Errorf("expected int to return %d, got %d", exp, ret.Int())
		}
	}
}
示例#7
0
func TestTimeNow(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	tm := new(TimeMod)
	tm.SetCtx(ctx)
	exp := time.Now()
	ret := tm.time_Now()
	ob := ret.(runtime.Object)
	if yr := ob.Get(runtime.String("Year")); yr.Int() != int64(exp.Year()) {
		t.Errorf("expected year %d, got %d", exp.Year(), yr.Int())
	}
	if mt := ob.Get(runtime.String("Month")); mt.Int() != int64(exp.Month()) {
		t.Errorf("expected month %d, got %d", exp.Month(), mt.Int())
	}
	if dy := ob.Get(runtime.String("Day")); dy.Int() != int64(exp.Day()) {
		t.Errorf("expected day %d, got %d", exp.Day(), dy.Int())
	}
	if hr := ob.Get(runtime.String("Hour")); hr.Int() != int64(exp.Hour()) {
		t.Errorf("expected hour %d, got %d", exp.Hour(), hr.Int())
	}
	if mn := ob.Get(runtime.String("Minute")); mn.Int() != int64(exp.Minute()) {
		t.Errorf("expected minute %d, got %d", exp.Minute(), mn.Int())
	}
	if sc := ob.Get(runtime.String("Second")); sc.Int() != int64(exp.Second()) {
		t.Errorf("expected second %d, got %d", exp.Second(), sc.Int())
	}
	if ns := ob.Get(runtime.String("Nanosecond")); ns.Int() < int64(exp.Nanosecond()) {
		t.Errorf("expected nanosecond %d, got %d", exp.Nanosecond(), ns.Int())
	}
}
示例#8
0
func TestStringsTrim(t *testing.T) {
	cases := []struct {
		args []runtime.Val
		exp  string
	}{
		0: {
			args: []runtime.Val{
				runtime.String(" "),
			},
			exp: "",
		},
		1: {
			args: []runtime.Val{
				runtime.String("\n  \t   hi \r"),
			},
			exp: "hi",
		},
		2: {
			args: []runtime.Val{
				runtime.String("xoxolovexox"),
				runtime.String("xo"),
			},
			exp: "love",
		},
	}
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	for i, c := range cases {
		ret := sm.strings_Trim(c.args...)
		if ret.String() != c.exp {
			t.Errorf("[%d] - expected %s, got %s", i, c.exp, ret)
		}
	}
}
示例#9
0
func TestFilepathBaseDirExt(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	fm := new(FilepathMod)
	fm.SetCtx(ctx)
	p, e := filepath.Abs("./testdata/readfile.txt")
	if e != nil {
		panic(e)
	}
	// Base
	exp := filepath.Base(p)
	ret := fm.filepath_Base(runtime.String(p))
	if ret.String() != exp {
		t.Errorf("expected base '%s', got '%s'", exp, ret.String())
	}
	// Dir
	exp = filepath.Dir(p)
	ret = fm.filepath_Dir(runtime.String(p))
	if ret.String() != exp {
		t.Errorf("expected dir '%s', got '%s'", exp, ret.String())
	}
	// Ext
	exp = filepath.Ext(p)
	ret = fm.filepath_Ext(runtime.String(p))
	if ret.String() != exp {
		t.Errorf("expected extension '%s', got '%s'", exp, ret.String())
	}
}
示例#10
0
func TestStringsToUpper(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_ToUpper(runtime.String("this"), runtime.String("Is"), runtime.String("A"), runtime.String("... strInG"))
	exp := "THISISA... STRING"
	if ret.String() != exp {
		t.Errorf("expected %s, got %s", exp, ret)
	}
}
示例#11
0
func TestTimeSleep(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	tm := new(TimeMod)
	tm.SetCtx(ctx)
	n := time.Now()
	tm.time_Sleep(runtime.Number(100))
	if diff := time.Now().Sub(n); diff < 100*time.Millisecond {
		t.Errorf("expected at least 100ms, got %f", diff.Seconds()*1000)
	}
}
示例#12
0
func TestStringsConcat(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_Concat(runtime.String("hello"), runtime.Number(12), runtime.Bool(true), runtime.String("end"))
	exp := "hello12trueend"
	if ret.String() != exp {
		t.Errorf("expected %s, got %s", exp, ret)
	}
}
示例#13
0
func TestFmtScanint(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	buf := bytes.NewBuffer([]byte("12\n"))
	ctx.Stdin = buf
	fm := new(FmtMod)
	fm.SetCtx(ctx)
	ret := fm.fmt_Scanint()
	if ret.Int() != 12 {
		t.Errorf("expected 12, got %d", ret.Int())
	}
}
示例#14
0
func TestOsExec(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	exp := "hello"
	ret := om.os_Exec(runtime.String("echo"), runtime.String(exp))
	// Shell adds a \n after output
	if ret.String() != exp+"\n" {
		t.Errorf("expected '%s', got '%s'", exp, ret)
	}
}
示例#15
0
func TestMathNaN(t *testing.T) {
	// This is just an interface to Go's function, so just a quick simple test
	ctx := runtime.NewCtx(nil, nil)
	mm := new(MathMod)
	mm.SetCtx(ctx)
	ret := mm.math_NaN()
	exp := math.NaN()
	if math.IsNaN(ret.Float()) != math.IsNaN(exp) {
		t.Errorf("expected NaN, got %f", ret.Float())
	}
}
示例#16
0
func TestMathIsNaN(t *testing.T) {
	// This is just an interface to Go's function, so just a quick simple test
	ctx := runtime.NewCtx(nil, nil)
	mm := new(MathMod)
	mm.SetCtx(ctx)
	val := 0.12
	ret := mm.math_IsNaN(runtime.Number(val))
	exp := math.IsNaN(val)
	if ret.Bool() != exp {
		t.Errorf("expected %v, got %v", exp, ret.Bool())
	}
}
示例#17
0
func TestMathTanh(t *testing.T) {
	// This is just an interface to Go's function, so just a quick simple test
	ctx := runtime.NewCtx(nil, nil)
	mm := new(MathMod)
	mm.SetCtx(ctx)
	val := 1.12
	ret := mm.math_Tanh(runtime.Number(val))
	exp := math.Tanh(val)
	if ret.Float() != exp {
		t.Errorf("expected %f, got %f", exp, ret.Float())
	}
}
示例#18
0
func TestStringsHasSuffix(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_HasSuffix(runtime.String("suffix, you say"), runtime.String("ay"), runtime.Nil, runtime.Number(3), runtime.String("wh"))
	if !ret.Bool() {
		t.Errorf("expected true, got false")
	}
	ret = sm.strings_HasSuffix(runtime.String("suffix, you say"), runtime.String("no"), runtime.Nil, runtime.Number(3), runtime.String("hw"))
	if ret.Bool() {
		t.Errorf("expected false, got true")
	}
}
示例#19
0
func TestStringsContains(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_Contains(runtime.String("contains something"), runtime.String("what"), runtime.Nil, runtime.Number(3), runtime.String("some"))
	if !ret.Bool() {
		t.Errorf("expected true, got false")
	}
	ret = sm.strings_Contains(runtime.String("contains something"), runtime.String("no"), runtime.Nil, runtime.Number(3), runtime.String("hw"))
	if ret.Bool() {
		t.Errorf("expected false, got true")
	}
}
示例#20
0
func TestOsGetwd(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	exp, e := os.Getwd()
	if e != nil {
		panic(e)
	}
	ret := om.os_Getwd()
	if ret.String() != exp {
		t.Errorf("expected '%s', got '%s'", exp, ret.String())
	}
}
示例#21
0
func TestFmtScanln(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	buf := bytes.NewBuffer([]byte(`This is
two lines
`))
	ctx.Stdin = buf
	fm := new(FmtMod)
	fm.SetCtx(ctx)
	ret := fm.fmt_Scanln()
	if ret.String() != "This is" {
		t.Errorf("expected line 1 to be 'This is', got '%s'", ret)
	}
}
示例#22
0
func TestPi(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	mm := new(MathMod)
	mm.SetCtx(ctx)
	ob, err := mm.Run()
	if err != nil {
		panic(err)
	}
	ret := ob.(runtime.Object).Get(runtime.String("Pi"))
	exp := math.Pi
	if ret.Float() != exp {
		t.Errorf("expected %f, got %f", exp, ret.Float())
	}
}
示例#23
0
func TestOsGetenv(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	exp := "ok"
	e := os.Setenv("TEST", exp)
	if e != nil {
		panic(e)
	}
	ret := om.os_Getenv(runtime.String("TEST"))
	if ret.String() != exp {
		t.Errorf("expected '%s', got '%s'", exp, ret.String())
	}
}
示例#24
0
func TestOsReadFile(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	b, e := ioutil.ReadFile("./testdata/readfile.txt")
	if e != nil {
		panic(e)
	}
	exp := string(b)
	ret := om.os_ReadFile(runtime.String("./testdata/readfile.txt"))
	if ret.String() != exp {
		t.Errorf("expected '%s', got '%s'", exp, ret.String())
	}
}
示例#25
0
func TestStringsSlice(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_Slice(runtime.String("agora"), runtime.Number(2))
	exp := "ora"
	if ret.String() != exp {
		t.Errorf("expected %s, got %s", exp, ret)
	}
	ret = sm.strings_Slice(runtime.String("agora"), runtime.Number(2), runtime.Number(4))
	exp = "or"
	if ret.String() != exp {
		t.Errorf("expected %s, got %s", exp, ret)
	}
}
示例#26
0
func TestFilepathJoin(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	fm := new(FilepathMod)
	fm.SetCtx(ctx)
	parts := []string{"./testdata", "..", "../../compiler", "test"}
	exp := filepath.Join(parts...)
	vals := make([]runtime.Val, len(parts))
	for i, s := range parts {
		vals[i] = runtime.String(s)
	}
	ret := fm.filepath_Join(vals...)
	if ret.String() != exp {
		t.Errorf("expected '%s', got '%s'", exp, ret.String())
	}
}
示例#27
0
func TestStringsLastIndex(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	ret := sm.strings_LastIndex(runtime.String("agoragore"), runtime.String("arg"), runtime.Nil, runtime.Number(3), runtime.String("go"))
	exp := 5
	if ret.Int() != int64(exp) {
		t.Errorf("expected %d, got %d", exp, ret.Int())
	}
	ret = sm.strings_Index(runtime.String("agoragore"), runtime.Number(6), runtime.String("arg"), runtime.Nil, runtime.Number(3), runtime.String("go"))
	exp = -1
	if ret.Int() != int64(exp) {
		t.Errorf("expected %d, got %d", exp, ret.Int())
	}
}
示例#28
0
func TestStringsReplace(t *testing.T) {
	cases := []struct {
		args []runtime.Val
		exp  string
	}{
		0: {
			args: []runtime.Val{
				runtime.String("this is the source"),
				runtime.String("th"),
			},
			exp: "is is e source",
		},
		1: {
			args: []runtime.Val{
				runtime.String("this is the source"),
				runtime.String("th"),
				runtime.Number(1),
			},
			exp: "is is the source",
		},
		2: {
			args: []runtime.Val{
				runtime.String("this is the source"),
				runtime.String("t"),
				runtime.String("T"),
			},
			exp: "This is The source",
		},
		3: {
			args: []runtime.Val{
				runtime.String("this is the source"),
				runtime.String("t"),
				runtime.String("T"),
				runtime.Number(1),
			},
			exp: "This is the source",
		},
	}
	ctx := runtime.NewCtx(nil, nil)
	sm := new(StringsMod)
	sm.SetCtx(ctx)
	for i, c := range cases {
		ret := sm.strings_Replace(c.args...)
		if ret.String() != c.exp {
			t.Errorf("[%d] - expected %s, got %s", i, c.exp, ret)
		}
	}
}
示例#29
0
文件: agora.go 项目: jmptrader/agora
func (r *run) Execute(args []string) error {
	if len(args) < 1 {
		return fmt.Errorf("expected an input file")
	}
	var c runtime.Compiler
	if r.FromAsm {
		c = new(compiler.Asm)
	} else {
		c = new(compiler.Compiler)
	}
	ctx := runtime.NewCtx(new(runtime.FileResolver), c)
	if !r.NoStdlib {
		// Register the standard lib's Fmt package
		ctx.RegisterNativeModule(new(stdlib.FmtMod))
		ctx.RegisterNativeModule(new(stdlib.FilepathMod))
		ctx.RegisterNativeModule(new(stdlib.StringsMod))
		ctx.RegisterNativeModule(new(stdlib.MathMod))
		ctx.RegisterNativeModule(new(stdlib.OsMod))
		ctx.RegisterNativeModule(new(stdlib.TimeMod))
	}
	ctx.Debug = r.Debug
	m, err := ctx.Load(args[0])
	if err != nil {
		return err
	}
	// Prepare extra parameters to send to module
	vals := make([]runtime.Val, len(args)-1)
	for i, s := range args[1:] {
		vals[i] = runtime.String(s)
	}
	// Open output stream
	outf := os.Stdout
	if r.Output != "" {
		outf, err = os.Open(r.Output)
		if err != nil {
			return err
		}
		defer outf.Close()
		ctx.Stdout = outf
	}
	res, err := m.Run(vals...)
	if err == nil && !r.NoResult {
		fmt.Fprintf(outf, "\n= %s (%T)\n", res, res)
	}
	return err
}
示例#30
0
func TestOsMkRemRenReadDir(t *testing.T) {
	ctx := runtime.NewCtx(nil, nil)
	om := new(OsMod)
	om.SetCtx(ctx)
	// First create directories
	d1, d2 := "./testdata/d1", "./testdata/d2/d3"
	om.os_Mkdir(runtime.String(d1), runtime.String(d2))
	// Check that they exist
	if _, e := os.Stat(d1); os.IsNotExist(e) {
		t.Errorf("expected d1 to be created, got %s", e)
	} else if e != nil {
		panic(e)
	}
	if _, e := os.Stat(d2); os.IsNotExist(e) {
		t.Errorf("expected d2 to be created, got %s", e)
	} else if e != nil {
		panic(e)
	}
	// Create a file
	fn := filepath.Join(d2, "test.txt")
	om.os_WriteFile(runtime.String(fn), runtime.String("hi"))
	// Read the dir
	ret := om.os_ReadDir(runtime.String(d2))
	ob := ret.(runtime.Object)
	if ob.Len().Int() != 1 {
		t.Errorf("expected read dir to return 1 file, got %d", ob.Len().Int())
	}
	v := ob.Get(runtime.Number(0))
	ob = v.(runtime.Object)
	if s := ob.Get(runtime.String("Name")); s.String() != "test.txt" {
		t.Errorf("expected read file to be 'test.txt', got %s", s)
	}
	// Remove the first dir
	om.os_Remove(runtime.String(d1))
	if _, e := os.Stat(d1); !os.IsNotExist(e) {
		t.Errorf("expected d1 to be deleted, got %s", e)
	}
	// Remove all for the second dir and file
	d2 = filepath.Join(d2, "..")
	om.os_RemoveAll(runtime.String(d2))
	if _, e := os.Stat(d2); !os.IsNotExist(e) {
		t.Errorf("expected d2 to be deleted, got %s", e)
	}
}